MySQL:数据库优化方法总结
简介:
- 一共分为
6
个篇章 - 由
SQL
、索引
、缓存
、字段
、数据表
、数据库
组成
SQL:
避免 select *
从数据库里读出越多的数据,查询就变得越慢
如果数据库和 web服务器 是两台独立的服务器,还会增加网络传输的负载
limit 1
做查询时知道结果只有一条记录时使用
但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数
拆分大的 delete 或 insert 语句
因为这两个都会锁表,表锁住其他操作就执行不了,导致整个网站停止相应
预处理(Prepared Statements)
预处理很像存储过程,是一种运行在后台的SQL语句集合。
使用预处理可以获得很多好处,无论是性能、安全问题。
无缓冲的查询
执行一个SQL,程序会等待SQL返回,然后再往下继续执行。
可以使用无缓冲查询来改变这个行为。
explain select
可以分析查询语句、表结构的性能瓶颈。
主要参数:type、Extra
从 procedure analyse() 取得建议
procedure analyse() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议
只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的
使用一个对象关系映射器(Object Relational Mapper 简称:ORM)
使用 ORM 能够获得可靠的性能增涨
一个 ORM 可以做的所有事情,也能被手动的编写出来
小心 “永久链接”
一个链接被创建了会永远处在连接的状态,就算是数据库操作已经结束了
下一次的 HTTP 请求会重用 Apache 的子进程,并重用相同的 MySQL 链接
反范式化设计
空间换时间,避免 join,有些 join 操作可以在用代码实现,没必要用数据库来实现。
buffer
尽量让内存大于数据
索引:
为搜索字段建索引
索引并不一定就是给主键或是唯一的字段
如果在你的表中,有某个字段你总要会经常用来做搜索,请为其建立索引
JOIN 表使用相同类型的列,并将其索引
如果你使用了很多 join 查询,应该确认两个表中 join 的字段建过索引
MySQL内部会启动为你优化 join 的 SQL语句 的机制
每张表设置一个ID
每张表设置一个ID做为其主键,最好是一个INT型(推荐使用 unsigned)
并设置上自动增加的 auto_increment 标志
缓存:
开启查询缓存
开启查询缓存提高性能最有效的方法之一
相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中
后续相同的查询就不用操作表而直接访问缓存了
字段:
越小的列会越快
对数据库来说硬盘操作可能是最重大的瓶颈
所以把数据变得紧凑可以减少对硬盘的访问
使用 enum 而不是 varchar
enum 类型是非常快和紧凑的。实际保存的是 tinyint,但显示的是字符串
用这个字段来做一些选项列表变得相当的完美。
尽可能使用 not null
除非你有很特别的原因去使用 null
你应该让你的字段保持 not null
把IP地址存成 unsigned int
很多程序员都会创建一个 varchar(15) 字段来存放字符串形式的 IP 而不是整形的 IP
如果你用整形来存放,只需要4个字节,并且你可以有定长的字段
而且,这会为你带来查询上的优势,尤其是当你需要使用这样的WHERE条件:IP between ip1 and ip2
固定长度的表会更快
如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”
如果表中没有如下类型的字段: varchar、text、blob
只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了
这样,MySQL 引擎会用另一种方法来处理
数据表:
选择正确的存储引擎
两个存储引擎 MyISAM 和 InnoDB
每个引擎都有利有弊
垂直分割
降低表的复杂度和字段的数目
水平分割
根据一列或多列数据的值把数据行放到两个独立的表中
表分区
已一定的区间为一个分区表
将原始表划分成多个分区表
数据库:
选择正确的编码
国外UTF-8、中国GBK、大陆GB2312
主从复制/读写分离
主数据库使用 InnoDB、从数据库使用 MyISAM
主数据库创建用户让从数据库登录复制
通过 bin-log 实现数据传输
bin-log 只保存更新的数据