查看“WHERE子句优化”的源代码
←
WHERE子句优化
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
本节讨论了处理WHERE子句时可以进行的优化。示例使用SELECT语句,但相同的优化也适用于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) *常量折叠: (a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5 *常量条件删除: (b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=7 AND 5=6) -> b=5 OR b=6 在MySQL 8.0.14及更高版本中,这是在准备阶段进行而不是在优化阶段进行的,这有助于简化连接。 *索引使用的常量表达式只会计算一次。 *从MySQL 8.0.16开始,比较数值类型的列与常量值,如果值无效或超出范围,则会进行检查、折叠或删除: # CREATE TABLE t (c TINYINT UNSIGNED NOT NULL); SELECT * FROM t WHERE c ≪ 256; -≫ SELECT * FROM t WHERE 1; *对于没有WHERE子句的单个表的COUNT(*)查询,对于MyISAM和MEMORY表,直接从表信息中检索。当与一个表一起使用时,对于任何NOT NULL表达式也是如此。 *早期检测无效的常量表达式。MySQL快速检测到某些SELECT语句是不可能的,并返回零行。 *如果不使用GROUP BY或聚合函数(COUNT()、MIN()等),HAVING会与WHERE合并。 *对于连接中的每个表,将构造一个简化的WHERE子句,以获得对表的快速WHERE评估,并尽早跳过行。 *在查询中的其他任何表之前,首先读取所有常量表。常量表包括以下内容: #空表或只有一行的表。 #用于具有WHERE子句的主键或唯一索引的表,其中所有索引部分与常量表达式进行比较,并定义为NOT NULL。 以下所有表都被用作常量表: SELECT * FROM t WHERE primary_key=1; SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id; *在尝试所有可能的情况下,找到连接表的最佳连接组合。如果ORDER BY和GROUP BY子句中的所有列都来自同一张表,则在连接时首选该表。 *如果存在ORDER BY子句和不同的GROUP BY子句,或者ORDER BY或GROUP BY包含来自连接队列中第一个表以外的表的列,则创建一个临时表。 *如果使用SQL_SMALL_RESULT修饰符,MySQL将使用内存中的临时表。 *查询每个表索引,并使用最佳索引,除非优化器认为使用表扫描更有效。过去,基于最佳索引是否跨越了表的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_name WHERE key_part1=constant; SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10; SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10; 假设索引列是数值型的情况下,MySQL仅使用索引树来解析以下查询: SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val; SELECT COUNT(*) FROM tbl_name WHERE key_part1=val1 AND key_part2=val2; SELECT MAX(key_part2) FROM tbl_name GROUP BY key_part1; 以下查询使用索引以排序的方式检索行,无需进行额外的排序操作: SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ; SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... ;
返回至“
WHERE子句优化
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
基础知识
正则表达式
Markdown
分布式
项目管理
系统集成项目管理基础知识
云原生
Docker
云原生安全
云原生词汇表
十二因素应用
Kubernetes
音频处理
音频合成
Edge-tts
CMS系统
Docsify
VuePress
Mediawiki
自动生成
Marp
CI/CD
GitLab
设计
颜色
平面设计
AI
数字人
操作系统
GNU/Linux
数据库
Mysql
工具
链入页面
相关更改
特殊页面
页面信息