第二章 select语句优化 (一) —— where子语句优化

本节讨论可以进行的优化 处理条款。这些示例使用 SELECT 语句,但相同 优化适用于 DELETEUPDATE 语句中的子句。

注意

因为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

在MySQL8.0.14和后来,这个过程中发生制而不是在优化阶段,它有助于简化的加入。 见第8.2.1.9"外层参加的最优化",为进一步的信息和实例。

  • 恒的表达方式用通过指数进行评估,只有一次。

  • 开始与MySQL8.0.16,比较分列的数值类型与常值检查和折叠或删除无效或愤怒的价值观:

CREATE TABLE t (c TINYINT UNSIGNED NOT NULL);
  SELECT * FROM t WHERE c ≪ 256;
-≫ SELECT * FROM t WHERE 1;
  • 最(*)在一个表中没有哪里是直接检索,从表中的信息些并存表。 这也是完成任何不NULL表时使用的只有一个表中。

  • 早期检测的无效恒的表达。 MySQL快速检测一些选择的陈述是不可能的和返回任何行。 具有合并在那里如果你不使用集团通过或集职能(COUNT(),MIN(),等等)。

  • 每个表格在一个加入、一个简单的凡是构成获得一个快速评价表,并且要跳过行尽快。 所有的恒表是第一次读之前的任何其他表格的查询。 一个常数表格是以下任一特性:

    • 空白表格或一个表格有一个行。

    • 一个表,使用的是与其条款的一个主要关键或一个独特的索引,其中所有索引的部分是较 为恒的表达,并定义为不NULL。

所有下列表格用作不断表:

SELECT * FROM t WHERE primary_key=1;
SELECT * FROM t1,t2
  WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
  • 最好加入的组合加入本表是发现通过尝试所有可能性。 如果所有列为了通过和组通过的条款来自同一个表格,该表是优选的第一个时候加入。

  • 如果有一个以通过的条款和不同的组通过的条款,或者如果该命令通过或组通过包含的列表,其他比第一个表中加入队列,一个临时的表创建。

  • 如果您使用的SQL_SMALL_RESULT修改,MySQL使用的存储器的临时表格。

  • 每一表格指数查询,最好的指标是使用,除非优化程序,认为这是更有效使用一个表格的扫描。 在同一时间,一个扫描被用来根据是否最好的指数跨区超过30%的表格,但是一个固定的百分比不再确定之间的选择使用的一个指数或扫描。 优化现在是更复杂的和基于其估计其他因素,如表格的大小、数量的排,并I/O块的大小。

  • 在某些情况下,MySQL可以读取行从索引,甚至没有咨询的数据文件。 如果所有列使用从指数的数字,只有索引树被用于解决所查询。

  • 之前的每一行为的输出,这些不匹配所具有的条款都跳过。

一些实例的问询是非常快:

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, ... ;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨慕晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值