索引优化与查询优化
- 索引失效、没有充分利用到索引---索引建立
- 关联查询太多 join(设计缺陷或不得已的需求)---SQL 优化
- 服务器调优及各个参数设置(缓冲、线程数等)---调整 my.cnf
- 数据过多----分库分表
- 物理优化:通过
索引
和表连接方式
等技术来进行优化。(索引的使用) - 逻辑查询优化:通过
SQL等价变换
提升查询效率/
索引失效案例
没有索引
没有索引,就需要对查询的字段创建索引。
SELECT SQL_NO_CACHE * FROM student WHERE age=38;
SELECT SQL_NO_CACHE * FROM student WHERE age=30 and classId=4;
SELECT SQL_NO_CACHE * FROM student WHERE age=30 and classId=4 AND name = 'abcd';
创建索引
CREATE INDEX idx_age oN student(age);
CREATE INDEX idx_age_classid ON student( age , classId);
CREATE INDEX idx_age_classid_name ON student(age,classId , name ) ;
最佳左前缀法则
MySQL可以为多个字段创建索引,一个索引可以包括16个字段。对于多列索引,过滤条件要使用索引必须按照索引建立时的顺序, 依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。如果查询条件中没有使用这些字段中第1个字段时,多列(或联合)索引不会被使用。
主键插入顺序
主键按照从小到大的顺序插入可以减少 页分裂
和 记录位移
等问题。(因为一个页面的数据都是有序的,如果页面满了,然后再向里面插入一条数据,就会出现页分裂的问题)
建议自定义的主键列 id 添加 AUTO_INCREMENT 属性。
计算、函数、类型转换(自动或手动)导致索引失效
CREATE INDEX idx_name ON student(NAME);
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%'; -- idx_name 索引生效
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc'; -- idx_name 索引失效
CREATE INDEX idx_sno ON student(stuno);
EXPLAIN SELECT SQL_NO_CACHE id,stuno,NAME FROM student WHERE stuno+1 = 900001; -- 索引失效
EXPLAIN SELECT SQL_NO_CACHE id,stuno,NAME FROM student WHERE stuno = 900000; -- 索引生效
类型转换导致索引失效
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name=123; -- 索引失效
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name='123'; -- 索引生效