制作精美网站建设服务周到,wordpress实现mp4播放器,旅游型网站的建设背景图片,唐山网站建设互众动力本节讨论可用于处理 WHERE 子句的优化。示例使用 SELECT 语句#xff0c;但相同的优化适用于 DELETE 和 UPDATE 语句中的 WHERE 子句。 注意 因为 MySQL 优化器的工作正在进行#xff0c;所以这里并没有记录 MySQL 执行的所有优化。 您可能会尝试重写查询以使算术运算更快但相同的优化适用于 DELETE 和 UPDATE 语句中的 WHERE 子句。 注意 因为 MySQL 优化器的工作正在进行所以这里并没有记录 MySQL 执行的所有优化。 您可能会尝试重写查询以使算术运算更快同时牺牲可读性。由于 MySQL 会自动进行类似的优化因此您通常可以避免这项工作并以更易于理解和维护的形式保留查询。MySQL 执行的一些优化如下 删除不必要的括号 ((a AND b) AND c OR (((a AND b) AND (c AND d))))
- (a AND b AND c) OR (a AND b AND c AND d)常量折叠 (ab AND bc) AND a5
- b5 AND bc AND a5移除常量条件 (b5 AND b5) OR (b6 AND 55) OR (b7 AND 56)
- b5 OR b6在 MySQL 8.0.14 及更高版本中这是在准备阶段而不是优化阶段进行的这有助于简化连接。有关更多信息和示例请参见 第 8.2.1.9 节 “外连接优化” 。 索引使用的常量表达式只计算一次。 从 MySQL 8.0.16 开始检查数值类型列与常量值的比较并折叠或删除无效或过时值 # CREATE TABLE t (c TINYINT UNSIGNED NOT NULL);SELECT * FROM t WHERE c ≪ 256;-≫ SELECT * FROM t WHERE 1;有关更多信息请参见 第 8.2.1.14 节 “常量折叠优化” 。 直接从 MyISAM 和 MEMORY 表的表信息中检索不带 WHERE 的单个表上的 COUNT(*) 。当只与一个表一起使用时这也适用于任何 NOT NULL 表达式。 提前检测到无效的常量表达式。MySQL 很快检测到某些 SELECT 语句是不可能的并且不返回任何行。 如果不使用 GROUP BY 或聚合函数 COUNT()、MIN() 等HAVING 将与 WHERE 合并。 对于联接中的每个表构造一个更简单的 WHERE 以获得表的快速 WHERE 求值并尽快跳过行。 在查询中的读取所有常量表在任何其他表之前优先读取。常量表是以下任意一种 空表或只有一行的表。与 PRIMARY KEY 或 UNIQUE 索引上的 WHERE 子句一起使用的表其中所有索引部分都与常量表达式进行比较并定义为 NOT NULL 。 以下所有表均用作常量表 SELECT * FROM t WHERE primary_key1;
SELECT * FROM t1,t2WHERE t1.primary_key1 AND t2.primary_keyt1.id;通过尝试所有可能性可以找到连接表的最佳连接组合。如果 ORDER BY 和 GROUP BY 子句中的所有列都来自同一个表则在连接时首先选择该表。 如果存在 ORDER BY 子句和不同的 GROUP BY 子句或者 ORDER BY 或 GROUP BY 包含联接队列中第一个表以外的表中的列则会创建一个临时表。 如果使用 SQL_SMALL_RESULT 修饰符MySQL 将使用内存in-memory临时表。 查询每个表索引并使用最佳索引除非优化器认为使用表扫描更有效。曾经扫描是基于最佳索引是否覆盖了表的 30% 以上但固定的百分比不再决定使用索引还是扫描。优化器现在更加复杂它的估计基于其他因素如表大小、行数和 I/O 块大小。 在某些情况下MySQL 可以从索引中读取行甚至不需要查阅数据文件。如果索引中使用的所有列都是数字则只使用索引树来解析查询。 在输出每一行之前将跳过与 HAVING 子句不匹配的行。
一些非常快速的查询示例
SELECT COUNT(*) FROM tbl_name;SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;SELECT MAX(key_part2) FROM tbl_nameWHERE key_part1constant;SELECT ... FROM tbl_nameORDER BY key_part1,key_part2,... LIMIT 10;SELECT ... FROM tbl_nameORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;MySQL 仅使用索引树解析以下查询假设索引列是数字
SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1val;SELECT COUNT(*) FROM tbl_nameWHERE key_part1val1 AND key_part2val2;SELECT MAX(key_part2) FROM tbl_name GROUP BY key_part1;以下查询使用索引按排序顺序检索行而无需单独的排序过程
SELECT ... FROM tbl_nameORDER BY key_part1,key_part2,... ;SELECT ... FROM tbl_nameORDER BY key_part1 DESC, key_part2 DESC, ... ;