文章目录
- MySQL 基于规则的优化 (RBO):
MySQL 基于规则的优化 (RBO):
MySQL 查询优化器除了成本优化 (CBO) 外,还包含一套基于规则的优化 (Rule-Based Optimization, RBO) 策略。RBO 就像 SQL 查询的 “整形医生”,依据预定义的规则,对查询进行快速的语法和语义转换,提升查询效率。
RBO 的核心思想:模式匹配与规则应用
RBO 的核心是 模式匹配 (Pattern Matching) 与规则应用 (Rule Application)。优化器预定义了一系列优化规则, 描述特定 SQL 模式的优化转换方式。优化器解析 SQL 查询时, 会尝试将查询与 RBO 规则进行匹配。如果匹配成功,则应用规则,对查询进行改写, 生成一个语义等价但可能更高效的新查询。
RBO 的主要优化规则
查询重写 (Query Rewrite) / 查询转换 (Query Transformation)
这是 RBO 最核心的功能,通过改写 SQL 语句本身来优化。
子查询优化 (Subquery Optimization) - RBO 的重中之重
子查询是常见的性能瓶颈。RBO 针对不同类型的子查询,应用不同的优化规则。
非相关子查询 (Non-Correlated Subquery) 优化
子查询的执行不依赖于外部查询的表。RBO 倾向于将非相关子查询 物化 (Materialization) 或 转换为连接 (Unnesting)。
IN
** 子查询转换为**JOIN**
(Subquery Unnesting - IN to JOIN)😗* 将WHERE column IN (SELECT ...)
形式的非相关IN
子查询,转换为等价的INNER JOIN
或LEFT SEMI JOIN
。
-- 原始 SQL (IN 子查询)
SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE region = 'North');
-- RBO 转换后的 SQL (JOIN)
SELECT o.* FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id
WHERE c.region = 'North';
机制详解: RBO 识别出 IN 子查询是非相关的,并且子查询的目的是过滤 orders 表的 customer_id。 因此,它将子查询提取出来,与外部查询的 orders 表进行 INNER JOIN 连接,连接条件是 o.customer_id = c.customer_id。 WHERE c.region = ‘North’ 条件被保留。
SELECT * FROM orders o WHERE o.customer_id IN (SELECT c.customer_id FROM customers c WHERE c.coutry=o.contry);
注:当子查询引用了外部查询的列时(相关子查询),其结果依赖于外部查询的每一行,外部查询每一行都需要执行一次子查询,非相关子查询
EXISTS
** 子查询转换为**JOIN**
(Subquery Unnesting - EXISTS to JOIN)😗* 将WHERE EXISTS (SELECT ...)
形式的非相关EXISTS
子查询,转换为LEFT SEMI JOIN
。
-- 原始 SQL (EXISTS 子查询)
SELECT * FROM departments WHERE EXISTS (SELECT * FROM employees WHERE dept_id = departments.dept_id AND salary >