查询及优化

查询优化器的局限性

关联子查询

在 where 条件中包含 IN() 的子查询语句,MySQL 执行时并不是先执行子查询然后执行外层查询。考虑使用 EXISTS() 来代替

UNION 的限制

无法将限制条件下推到内层。如果利用 union 合并结果集,希望各个子句根据 limit 只取部分结果或者对结果集先排序在合并,那么需要在各个子句中分别使用 limit 或者排序。

索引合并优化

where 条件中包含多个复杂条件的时候,MySQL 可以访问单个表的多个索引以合并和交叉过滤的方式来定位需要查找的行

等值传递

等值传递有可能造成额外的消耗。例如过大的 IN() 列表,而优化器发现存在 where、in 或者 using 子句,会将列表和另一个表的某列关联,这又可能导致优化和执行变慢。

并行执行

MySQL 无法利用多核来执行查询

哈希关联

MySQL 的关联都是循环嵌套关联,不支持哈希关联。如果使用的是 Memory 存储引擎,使用的是哈希索引,关联也类似于哈希关联。

松散索引扫描

不支持松散索引扫描,无法按照不连续的方式扫描一个索引。MySQL 索引的扫描需要有一个起点和终点。

最大值和最小值优化

当 where 条件中的字段列没有索引时,此时不管求那个列的最值,都会进行全表扫描

同表查询和更新

MySQL 不允许在一个 SQL 中对同一张表同时进行查询和更新

查询优化器的提示

  • HIGH_PRIORITY、LOW_PRIORITY:标示语句的优先级,例如 HIGH_PRIORITY 用于 select 语句时,MySQL 会将该语句调度到所有正在等代表锁修改数据的语句之前。
  • DELAYED:对 insert 和 replace 有效,立即返回客户端然后将插入的行数据放到缓冲区在表空闲时将数据批量插入。适合于日志系统或者客户端大量写入并不需要等待插入结果的业务应用。这样会导致 LAST_INSERT_ID() 函数无法工作。
  • STRAIGHT_JOIN:放置在 select 关键字后让查询中所有的表按照在语句中出现的顺序进行关联;放在两个关联表的名字中间时固定其前后两个表的关联顺序。
  • SQL_SMALL_RESULT、SQL_BIG_RESULT:这两个提示只对 select 有效,告诉优化器对 group by 和 distinct 查询如何使用临时表及排序,结果集小放在内存临时表;结果集大建议放在磁盘临时表做排序。
  • SQL_BUFFER_RESULT:让查询优化器将查询结果放到临时表,然后尽可能快的释放表锁
  • SQL_CACHE、SQL_NO_CACHE:查询结果是否应该放在查询缓存中
  • SQL_CALC_FOUND_ROWS:会计算除去 limit 子句后这个查询需要返回的所有结果集总数,对实际查询结果不影响。
  • FOR UPDATE、LOCK IN SHARE MODE:控制了 select 语句的锁机制,只对实现了行锁存储引擎有效。
  • USING INDE、IGNORE INDEX、FORCE INDEX:使用或者不使用哪些索引来查询

优化特定类型的查询

优化 count() 查询

count() 聚合函数可以统计某个列值的数量,在统计列值要求非空(不统计NULL);也可以统计行数,count() 统计结果集的行数,\ 并不会扩展成所有列,而是忽略所有列直接统计行数

优化关联查询

  • 确保 on 或者 using 子句的列上有索引
  • 确保任何的 group by 和 order by 表达式只涉及到一个表,这样 MySQL 才有可能利用索引来优化

优化子查询

优化 group by 和 distinct

都可以使用索引来优化,当无法使用索引时 group by 使用临时表或者文件排序来做分组

优化 limit 分页

当 offset 偏移量较大时,MySQL 需要扫描多条记录才能到达目标位置。考虑使用索引覆盖扫描,做一次关联操作再返回所需的列。

优化 SQL_CALC_FOUND_ROWS

在 limit 语句上加上这个提示,MySQL 就会不管结果是否实际需要都会扫描所有满足条件的行返回总数,而不是达到 limit 限制就停止。

优化 union 查询

MySQL 通过创建填充临时表的方式来执行 union 查询,但是需要手工将 where、limit、order by 等子句下推到各个子查询中,以便优化器利用这些条件进行优化。如果不是要消除重复的行,则推荐使用 union all,如果没有没有 all,MySQL 会给临时表加上 DISTINCT 对临时表做唯一性检查,这样的代价是比较高的。

静态查询分析

解析查询日志、分析查询模式

使用用户自定义变量