mysql查询数据至少达到range级别【虽然是涉及到范围查找,但毕竟走了索引】,尽量达到ref级别
- 无索引设计让其走索引
- 少用范围查找【因为范围查找得到的数据太多】
- 联合索引要符合最左前缀
- 不要在索引上做任何操作,比如计算、函数、手动类型转换,会导致索引失效变成全表扫描
- 避免使用
select *
,尽量使用覆盖索引【不会回表查找】 - mysql在使用不等于!=操作时,无法使用索引,会导致全表扫描
- is null 、is not null一般情况下无法使用索引
- like通配符开头,会导致索引失效走全表扫描
- 少用or 、in【可能会导致索引树扫描多次】
补充:
碰到联表查询的时候:需要关联字段有索引,这样走嵌套循环连接算法【NLJ】
小表驱动大表,关联字段有索引
没有索引的话走基于块的循环连接算法【BNL】
要是不走BNL的话跟NLJ一样则更慢【比如小表100,大表10000条数据,则需扫描100万次】
走BNL算法的话是加入join_buffer,将小表的数据全量放到join_buffer中,然后扫描被驱动表,把被驱动表的数据每一行取出来跟join_buffer中的数据做对比,这样的话总扫描次数为10100次
in和exsits优化
原则:小表驱动大表
A表数据大于B表数据
select * from A where id in (select id from B)
A表数据小于B表数据
select * from A where id exsits (select 1 from B where B.id=A.id)