首页 > 数据库 > mysql教程 > 【连载】关系型数据库是如何工作的?(11)

【连载】关系型数据库是如何工作的?(11)

WBOY
发布: 2016-06-07 14:51:07
原创
1090 人浏览过

在重写这一步,我们拿到了查询SQL的内部表示,重写的目的是: 预优化SQL 避免不必要的操作 帮助优化器找到尽可能好的解决方案 重写器会在查询上匹配一系列规则,如果匹配一个规则就应用它重写查询,以下是部分可选的规则: 视图合并:如果你在查询中用了视图

在重写这一步,我们拿到了查询SQL的内部表示,重写的目的是:

  • 预优化SQL
  • 避免不必要的操作
  • 帮助优化器找到尽可能好的解决方案

重写器会在查询上匹配一系列规则,如果匹配一个规则就应用它重写查询,以下是部分可选的规则:

  • 视图合并:如果你在查询中用了视图,那么视图就会被转换为一段代码;
  • 优化子查询:由于一个子查询非常难以优化,因此重写器会修改子查询并删除子查询。
    例如:
<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">SELECT</span> PERSON.*
<span class="hljs-keyword">FROM</span> PERSON
<span class="hljs-keyword">WHERE</span> PERSON.person_key <span class="hljs-keyword">IN</span>
(<span class="hljs-keyword">SELECT</span> MAILS.person_key
<span class="hljs-keyword">FROM</span> MAILS
<span class="hljs-keyword">WHERE</span> MAILS.mail <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'christophe%'</span>);</span></code>
登录后复制

会被重写器转换为:

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">SELECT</span> PERSON.*
<span class="hljs-keyword">FROM</span> PERSON, MAILS
<span class="hljs-keyword">WHERE</span> PERSON.person_key = MAILS.person_key
<span class="hljs-keyword">and</span> MAILS.mail <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'christophe%'</span>;</span></code>
登录后复制
  • 移除不必要的操作:如果在某个或某组字段上使用了DISTINCT关键字,但是同时在这些字段上又增加了防止数据不唯一的唯一性约束,则重写器会移除DISTINCT;
  • 移除多余的join:如果两次使用同一个join条件(可能是一个join条件被视图所隐藏),或者可能因为传递性导致一个不必要的join,它们都会被移除;
  • 数学常量代换:如果你使用了一些数学运算,那么它只会被重写器计算一次。例如WHERE AGE > 10+2会被转换为WHERE AGE > 12、TODATE(“some date”) 会被转换为DateTime类型的日期;
  • (高级)分区优化:如果你使用的是分区表,重写器会找到实际使用的分区;
  • (高级)物化视图重写:如果有物化视图匹配查询的子集,重写器会检查其是否是最新的,并用物化视图替换实际的表;
  • (高级)定制规则:如果你为了修改查询(像Oracle策略)定制了一些规则,重写器会执行这些规则;

重写后的查询会被转发给优化器继续处理。

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板