【连载】关系型数据库是如何工作的?(11) - 查询管理器之rewriter
2016-05-09 21:13
274 查看
在重写这一步,我们拿到了查询SQL的内部表示,重写的目的是:
预优化SQL
避免不必要的操作
帮助优化器找到尽可能好的解决方案
重写器会在查询上匹配一系列规则,如果匹配一个规则就应用它重写查询,以下是部分可选的规则:
视图合并:如果你在查询中用了视图,那么视图就会被转换为一段代码;
优化子查询:由于一个子查询非常难以优化,因此重写器会修改子查询并删除子查询。
例如:
会被重写器转换为:
移除不必要的操作:如果在某个或某组字段上使用了DISTINCT关键字,但是同时在这些字段上又增加了防止数据不唯一的唯一性约束,则重写器会移除DISTINCT;
移除多余的join:如果两次使用同一个join条件(可能是一个join条件被视图所隐藏),或者可能因为传递性导致一个不必要的join,它们都会被移除;
数学常量代换:如果你使用了一些数学运算,那么它只会被重写器计算一次。例如WHERE AGE > 10+2会被转换为WHERE AGE > 12、TODATE(“some date”) 会被转换为DateTime类型的日期;
(高级)分区优化:如果你使用的是分区表,重写器会找到实际使用的分区;
(高级)物化视图重写:如果有物化视图匹配查询的子集,重写器会检查其是否是最新的,并用物化视图替换实际的表;
(高级)定制规则:如果你为了修改查询(像Oracle策略)定制了一些规则,重写器会执行这些规则;
重写后的查询会被转发给优化器继续处理。
预优化SQL
避免不必要的操作
帮助优化器找到尽可能好的解决方案
重写器会在查询上匹配一系列规则,如果匹配一个规则就应用它重写查询,以下是部分可选的规则:
视图合并:如果你在查询中用了视图,那么视图就会被转换为一段代码;
优化子查询:由于一个子查询非常难以优化,因此重写器会修改子查询并删除子查询。
例如:
SELECT PERSON.* FROM PERSON WHERE PERSON.person_key IN (SELECT MAILS.person_key FROM MAILS WHERE MAILS.mail LIKE 'christophe%');
会被重写器转换为:
SELECT PERSON.* FROM PERSON, MAILS WHERE PERSON.person_key = MAILS.person_key and MAILS.mail LIKE 'christophe%';
移除不必要的操作:如果在某个或某组字段上使用了DISTINCT关键字,但是同时在这些字段上又增加了防止数据不唯一的唯一性约束,则重写器会移除DISTINCT;
移除多余的join:如果两次使用同一个join条件(可能是一个join条件被视图所隐藏),或者可能因为传递性导致一个不必要的join,它们都会被移除;
数学常量代换:如果你使用了一些数学运算,那么它只会被重写器计算一次。例如WHERE AGE > 10+2会被转换为WHERE AGE > 12、TODATE(“some date”) 会被转换为DateTime类型的日期;
(高级)分区优化:如果你使用的是分区表,重写器会找到实际使用的分区;
(高级)物化视图重写:如果有物化视图匹配查询的子集,重写器会检查其是否是最新的,并用物化视图替换实际的表;
(高级)定制规则:如果你为了修改查询(像Oracle策略)定制了一些规则,重写器会执行这些规则;
重写后的查询会被转发给优化器继续处理。
相关文章推荐
- 动态生成SQL Server视图作业
- 关于Ruby on Rails视图编写的一些建议
- SQL server 视图(view)介绍
- SQL编程之子查询及注意事项
- dba_indexes视图的性能分析
- 简析SQL Server数据库用视图来处理复杂的数据查询关系
- SQL SERVER先判断视图是否存在然后再创建视图的语句
- sql server判断数据库、表、列、视图是否存在
- update 子查询使用介绍
- MySQL入门教程(七)之视图
- ASP.NET Web API教程 创建Admin视图详细介绍
- ASP.NET MVC4入门教程(六):验证编辑方法和编辑视图
- Oracle Scott创建视图权限不足解决办法
- SQLite教程(三):数据表和视图简介
- MySQL查询优化:用子查询代替非主键连接查询实例介绍
- MySQL里面的子查询实例
- Mysql子查询IN中使用LIMIT应用示例
- oracle中的视图详解
- SQL学习笔记八 索引,表连接,子查询,ROW_NUMBER
- SQLServer 优化SQL语句 in 和not in的替代方案