sql语句优化的意义:数据量和查询时间是成正比,但是有的时候一个低效sql语句会使查询了极少的数据量却用了很长的查询时间。
究其原因,都是因为扫描的行数远远大于了返回的行数。导致查询浪费了很多时间,而索引的意义就是为了减少扫描的行数。所以优化sql语句的核心就是减少扫描的行数。
explain sql 的type字段可以看到对应的表的扫描类型(对应类型的级别和区别这里不介绍了),rows字段可以看到扫描的行数,
而优化语句就是要让type类型的级别越高越好,rows扫描的行数越少越好(type类型决定着rows扫描的行数)。
下面介绍的sql优化就不介绍那些 函数,or ,<>这种不走索引的优化了。
1、当需要单表有大量的数据,用到分页时的优化sql 应用场景:分页查询流水表
SELECT * FROM test a INNER JOIN (SELECT ID FROM test LIMIT 1500000, 10) b on a.ID = b.ID
先通过分页查询聚簇索引的ID,再和原表关联取交集。
或者
SELECT * FROM test a where ID >= (SELECT ID FROM test LIMIT 1500000,1) limit 10
先通过子查询查找1500000的ID,在通过范围查找。
2、group by 分组函数要使用标识列(主键列)来分组才能命中索引(如果用position表的外键来分组,不会走索引)
select * from account a,position b
where a.account_id = b.account_id group by a.account_id
3、在允许的情况下,对具有较好离散度的列单独创建索引(数据重复率越小,离散度越高。),这样可以提高该索引的使用弹性;对于离散度较差的列,通过对多列进行合理的组合来创建组合索引,虽然这样做在很大程度上降低了各个列的使用弹性,但是却可以发挥多个列的综合效应。
4、根据业务建立适当的联合索引,并且联合索引的列要包含查询返回的字段 ,可以防止回表(也称为覆盖索引)(可以根据explain sql中的Extra字段是user index来判断是否触发覆盖索引扫描)。
5、可以考虑将复杂查询,分解成多个简单查询。在业务层整合数据。
6、当一个sql 同时where了两个条件, 一个是范围, 一个是唯一条件. 如果范围在前面, 那唯一条件的索引便会失效.例如
select * from test where age > 30 and score = 60