where语句:
1. 在查询中先读取所有常量表,常量表包含一下两种类型:①空表或者只有一条记录的表②where查询的条件为表的主键或者唯一索引,有索引的列与常量比较并且是非空
2. join查询如果 ORDER BY
和GROUP BY
子句来自同一个表,那么在查询时首先选择该表。
3. 如果有一个ORDER BY
子句和一个不同的GROUP BY
子句,或者如果 ORDER BY
或者GROUP BY
包含除联接队列中第一个表以外的表的列,则会创建一个临时表。
4.查询每个表索引,并使用最佳索引,除非优化器认为使用全表扫描更高效。以前根据最佳索引扫描行是否超过表的30%,但固定百分比不再决定使用索引或扫描之间的选择。优化器现在更加复杂,并将其估计基于其他因素,如表大小,行数和I / O块大小
5.mysql分析器在优化分析阶段会把不能使用索引的条件进行整合,能够使用索引的条件进行合并,覆盖
demo: key1
使索引列 nonkey
非索引列
SELECT * FROM t1 WHERE (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z');
①开始条件:(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR(key1 < 'bar' AND nonkey = 4) OR(key1 < 'uux' AND key1 > 'z' )
②删除 nonkey = 4
和 key1 LIKE '%b'
因为他们不能使用索引.正确的方式把他们替换为TRUE
, 这样我们就不会丢失匹配的行
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR(key1 < 'bar' AND TRUE) OR(key1 < 'uux' AND key1 > 'z')
③分解查询条件
(key1 LIKE 'abcde%' OR TRUE)
总是真(key1 < 'uux' AND key1 > 'z')
总是假
④合并之后
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
⑤进一步优化
(key1 < 'abc') OR (key1 < 'bar')
⑥再进一步
(key1 < 'bar')
6.联合索引
在某些情况下,MySQL可以从索引中读取行,而无需咨询数据文件。如果索引中使用的所有列都是数字,则仅使用索引树来解析查询。
- 对于多个字段的联合索引,一旦从一个字段开始使用范围检索,则后面的条件不再使用索引