尽量避免NULL值
MySql难以优化可空列,可以用0,特殊值或空字符串代替。
B-TREE索引的局限
只能从索引最左列开始,不能跳过左边和中间的索引列,不能优化访问第一个范围条件右边的列。
HASH索引的局限:
如何确定合适的前缀索引长度:
分析选择性和最坏情况的选择性。
后缀索引:
有时也非常有用,比如想根据邮箱的域名汇总,就可以把后缀单独保存起来并建立索引。
聚集索引:
是一个以数据行为叶子节点的B-TREE索引,数据根据索引排序存储。覆盖索引可以算是小的聚集索引。
索引使用技巧总结:
支持多种过滤条件
创建索引时将最有选择性的列放在前面,但是如果某个列经常用作范围条件查询,那最好放在末尾。而选择性差的列也不是不可以放在前面,这样可以让索引支持多种过滤条件,例如列sex,选择性很差,但是大多数查询都会用到它,那就可以把它放到索引的前面,如果sex不在where列表中也可以通过加上 and sex in (M,F)来确保索引被用上。这样可以避免创建太多的索引。
避免多个范围条件
MySql中范围条件(between,<,><>)会使索引忽略后面的索引列,但是多个相等条件不会有这个局限(in), 所以当查询中出现两个范围条件时可以尝试把其中一个范围条件转换为多个相等条件(用in关键字)。如果不能转换,可以考虑某个范围条件不包含在索引列中。
优化排序
可以为下面查询创建索引(sex,rating):
select <cols> from tb where sex = 'M' order by rating limit 10;
但是对于需要分页显示请求不是第一页的数据时,还是会很慢。可以考虑只提取需要的列的主键再连接原表:
select <cols> from tb inner join (
select <cols> from tb where sex = 'M' order by rating limit 100000,10
) as x using(<pk>);
索引和表维护
如果遇到古怪的行为--例如发生了不该发生的错误--运行check table以确认表是否损坏。
如果表损坏,可以用repair table或无操作alter(alter table innodb_tb engine = innodb)来修复。
可以使用analyze table来更新索引统计。
可以用optimize table来减少索引和表的碎片。
优化Alter Table
在MySQL中alter table经常会导致表重建,如果数据量很大会非常慢。如果只是修改table的列信息,可以使用alter column来避免表重建(modify column会导致表重建):
alter table tb
alter column col set default ;
这个命令只修改了.frm文件而没有修改表,会非常快。
类似的通过只修改.frm文件快速alter table的方式如下(具有风险,做好数据备份):
建一张相同结构的空表,根据需要修改;
执行flush with read lock;
用这张新表的.frm文件覆盖原表的.frm文件;
执行unlock tables命令释放读取锁。
优化联接
只需要在联接中的第二个表上添加索引,在联接表A和B时使用了列c,并且优化器按照从B到A的顺序联接,就不需要在表B上添加索引。
确保GROUP BY或ORDER BY只引用一个表中的列,这样MySQL可以尝试对这些操作使用索引。