MySQL内核查询优化发生在sql执行之前,进一步的去提高这个sql的性能

条件化简

移除不必要的括号
  • 原条件:((a = 5 AND b = c) OR ((a > c) AND (c < 5)))
  • 优化器会去掉括号:(a = 5 and b = c) OR (a > c AND c < 5)
常量传递(constant_propagation)
  • 原条件:a = 5 AND b > a
  • 优化器会变为常量:a = 5 AND b > 5
移除没用的条件(trivial_condition_removal)
  • 原条件:(a < 1 and b = b) OR (a = 6 OR 5 != 5)
  • 可以被简化为:a < 1 OR a = 6
常量表检测
  • 使用主键等值匹配或者唯一二级索引列等值匹配作为搜索条件来查询某个表,MySQL觉得这两种查询花费的时间特别少,少到可以忽略,
  • 原条件:SELECT * FROM table1 INNER JOIN table2 ON table1.column1 = table2.column2 WHERE table1.primary_key = 1;
  • 优化后:SELECT table1表记录的各个字段的常量值, table2.* FROM table1 INNER JOIN table2 ON table1表column1列的常量值 = table2.column2;

外连接消除

  • 内连接的驱动表和被驱动表的位置可以相互转换,而左(外)连接和右(外)连接的驱动表和被驱动表是固定的。
  • 原sql:SELECT * FROM e1 LEFT JOIN e2 ON e1.m1 = e2.m2 WHERE e2.n2 IS NOT NULL;
  • 等价于:SELECT * FROM e1 INNER JOIN e2 ON e1.m1 = e2.m2 WHERE e2.m2 = 2;

子查询优化

一些子查询的概念
  • 标量子查询:只返回一个单一值的子查询
  • 行子查询:返回一条记录的子查询
  • 列子查询:查询出一个列的数据的子查询
  • 表子查询:包含很多条记录的子查询
  • 不相关子查询:查询可以单独运行出结果,而不依赖于外层查询的值
  • 相关子查询:子查询的执行需要依赖于外层查询的值
标量子查询、行子查询的执行方式
  • 从外层查询中获取一条记录
  • 然后从上一步骤中获取的那条记录中找出子查询中涉及到的值
MySQL对IN子查询的优化
  • in的内容很少:直接内存中处理
  • in的结果集很多:物化表(存储子查询结果集的临时表),他是一张临时表,临时表也会使用索引。
  • 物化表转连接:将in的语句变为连接查询
  • 将子查询转换为半连接(semi-join):只关心连接中是否有,不关心有几个!