• 视图重写和等价谓词重写


    还没看,先mark一下

    一、什么是视图重写?

    视图是数据库中基于表的一种对象,把对表的查询固化,这种固化就是视图。

    这里我们需要注意区分: 视图<——>物化视图<——>物化(技术),三者之间的关系。

    物化是将结果缓存至内存的方式,这里我们所说的视图,其结果是动态的,而物化视图的结果是一个固定结果,对于物化技术来说,是实现将结果放置于内存的技术手段。 创建视图的格式为: 视图的格式

    从这个格式这里我们理解下视图的定义,是基于表的,是一个对查询操作的结果的固化,这里我们说子查询实际上是说,视图的优化绝大部分都是可以转化为子查询的优化。 视图的类型:

    1)用SPJ格式构造的视图,称为简单视图

    CREATE VIEW v1 AS SELECT x, y, z FROM t;

    2)用非SPJ格式构造的视图(带有GROUPBY等操作),称为复杂视图

    CREATE VIEW v2 AS SELECT x, y, z FROM t ORDER BY x;

    什么是视图重写?

    1)查询语句中出现视图对象;

    2)查询优化后,视图对象消失;

    3)消失的视图对象的查询语句, 融合到初始查询语句中。

    这里首先是说存在视图为前提,优化后视图被转化为子查询并且融合到原查询语句中。

    例如: 视图重写1

    这里基于t_a表创建了一个视图v_a,然后基于视图查询满足条件为字段col_b>100的字段col_a的数值。经过分析后,视图重写为如上形式,最后,等价变化为基于表t_a的,然后基于视图查询满足条件为字段col_b>100的字段col_a的数值。从而我们得到视图重写的准则:

    1)MySQL支持对视图进行优化;

    2)优化方法是把视图转为对基表的查询,然后进行类似子查询的优化;

    3)MySQL通常只能重写简单视图,复杂视图不能重写。 视图重写2

    二、对于MySql来说如何使用视图重写优化视图?

    基于优化准则,我们通过几个实例开看下优化是如何达到的。视图重写3

    1)在简单视图上执行连接操作

    直接用视图和表做连接操作,查询执行计划如下:

    视图重写4视图重写5这里我们可以看到,视图在被优化后,视图消失了,并且成为了基表的一部分子查询。

    然后,我们对比下,在表上执行与简单视图等价的连接操作:视图重写6视图重写7

    对比下最后的处理后的语句:

    前者:

    from tt.t1 join tt.t1 join tt.t2

    后者:

    from tt.t1 join (

    /* select#2 */ select tt.t1.a1 AS a1,tt.t1.b1 AS b1,

       `tt`.`t2`.`a2` AS `a2`,`tt`.`t2`.`b2` AS `b2` 
    

    from tt.t1 join tt.t2t12

    明显可以看到后者的子查询没有被消除,而前者则完全成为了转化为对基表的查询,这里的结果明显前者优于后者。

    2)在简单视图上进行聚集操作

    基于表t1和t2的视图v_t_1_2,进行聚集操作:视图重写8视图重写9

    这里子查询没有被消除,但是视图转化为了子查询,优化完成。

    3)直接用视图和表做连接操作,并执行分组操作视图重写10视图重写11

    视图消失,转化为基于基表的子查询。

    4)直接用视图和表做连接操作,并执行分组和去重操作操作视图重写12视图重写13

    视图消失,转化为基于基表的子查询。

    5)在简单视图上执行外连接操作视图重写14视图重写15

    视图消失,转化为基于基表的子查询。

    6)直接用复杂视图和表做连接操作视图重写16视图重写17

    视图完全没有被转化,复杂视图无法被优化。

    三、什么是等价谓词重写?

    把逻辑表达式重写成等价的且效率更高的形式。优点是能有效提高查询执行效率,这里说的谓词实际就是我们平常使用的比如:in、like、or、not等。

    四、对于MySql来说如何实现等价谓词重写?

    常见的等价谓词重写有:

    1)LIKE规则

    LIKE谓词,是SQL标准支持的一种模式匹配比较操作;

    LIKE规则,是对LIKE谓词的等价重写,即改写LIKE谓词为其他等价的谓词,以更好地利用索引进行优化。 示例如:

    name LIKE ‘Abc%’

    重写为:

    name >=’Abc’ AND name <’Abd’

    应用LIKE规则的好处:

    转换前针对LIKE谓词,只能进行全表扫描,如果name列上存在索引,则转换后可以进行索引扫描。

    LIKE其他形式还可以转换,例如:

    LIKE匹配的表达式中,没有通配符(%或_),则与“=”等价,

    如:

    name LIKE ‘Abc’

    重写为:

    name =’Abc’

    如果name列上存在索引,则可以利用索引提高查询效率。

    2)BETWEEN-AND规则

    BETWEEN-AND谓词,是SQL标准支持的一种范围比较操作;

    BETWEEN-AND规则,是BETWEEN-AND谓词的等价重写,即改写BETWEEN-AND谓词为其他等价的谓词,以更好地利用索引进行优化。

    例如:

    sno BETWEEN 10 AND 20

    重写为:

    sno>=10 AND sno <=20

    应用BETWEEN-AND规则的好处是:

    如果sno上建立了索引,则可以用索引扫描代替原来BETWEEN-AND谓词限定的全表扫描,从而提高了查询的效率。

    3)IN转换OR规则

    说明:IN是只IN操作符操作,不是IN子查询。

    IN转换OR规则,就是IN谓词的OR等价重写,即改写IN谓词为等价的OR谓词,以更好地利用索引进行优化。将IN谓词等价重写为若干个OR谓词,可能会提高执行效率。

    例如:

    age IN (8,12,21)

    重写为:

    age=8 OR age=12 OR age=21

    应用IN转换OR规则后效率是否能够提高,需要看数据库对IN谓词是否只支持全表扫描。

    如果数据库对IN谓词只支持全表扫描且OR谓词中表的age列上存在索引,则转换后查询效率会提高。

    将IN谓词等价重写为ANY谓词,可能会提高执行效率。

    例如:

    age IN (8,12,21)

    重写为: age ANY(8, 12, 21)

    应用IN转换ANY规则后效率是否能够提高,依赖于数据库对于ANY操作的支持情况。

    4)OR转换ANY规则

    OR转换ANY规则,就是OR谓词的ANY等价重写,即改写OR谓词为等价的ANY谓词,以更好地利用MIN/MAX操作进行优化。

    例如:

    sal>1000 OR

    dno=3 AND (sal>1100 OR sal>base_sal+100) OR

    sal>base_sal+200 OR

    sal>base_sal×2

    重写为:

    dno=3 AND (sal>1100 OR sal>base_sal+100) OR

    sal> ANY (1000,base_sal+200,base_sal×2)

    OR转换ANY规则,依赖于数据库对于ANY操作的支持情况。

    PostgreSQL V9.2.3和MySQL V5.6.10目前都不支持本条规则。

    5)ALL/ANY转换集函数规则

    ALL/ANY转换集函数规则,就是ALL/ANY谓词改写为等价的聚集函数MIN/MAX谓词操作,以更好地利用MIN/MAX操作进行优化。

    例如:

    sno>ANY(10, 2*5+3,sqrt(9))

    重写为:

    sno>sqrt(9)

    上面这个ALL/ANY转换集函数规则的示例,有两点需要注意:

    1)示例中存在“>”和“ANY”,其意是在找出“(10, 2*5+3,sqrt(9))”中的最小值,所以可以重写为“sno>sqrt(9)”。

    通常,聚集函数MAX()、MIN()等的执行效率一般都比ANY、ALL谓词的执行效率高,因此在这种情况下对其进行重写,可以起到比较好的效果。

    2)如果有索引存在,求解MAX/MIN的效率更高。

    6)NOT规则

    NOT谓词的等价重写,如下:

    NOT (col_1 !=2) 重写为 col_1=2

    NOT (col_1 !=col_2)重写为 col_1=col_2

    NOT (col_1 =col_2) 重写为 col_1!=col_2

    NOT (col_1 <col_2) 重写为 col_1>=col_2

    NOT (col_1 >col_2) 重写为 col_1<=col_2

    NOT规则重写的好处:

    如果col_1上建立了索引,则可以用索引扫描代替原来的全表扫描,从而提高查询的效率。

    7)OR重写并集规则

    OR条件重写为并集操作,形如下SQL示例:

    SELECT *

    FROM student

    WHERE(sex=’f’ AND age>15) OR age>18;

    假设所有条件表达式的列上都有索引(即sex列和age列上都存在索引),数据库可能对于示例中的WHERE语句强迫查询优化器使用顺序 扫描,因为这个语句要检索的是OR操作的集合。

    为了能利用索引处理上面的查询,可以将语句改成如下形式:

    SELECT *

    FROM student

    WHERE sex=’f’ and age>15

    UNION

    SELECT *

    FROM student

    WHERE age>18;

    改写后的形式,可以分别利用列sex和age上的索引,进行索引扫描,然后再提供执行UNION操作获得最终结果。

    总结,视图重写可以将视图转化为基于基表的子查询,而谓词重写则可以为诸如建立索引提高性能而提供帮助,但是,实际会不会提高性能还需要根据数据库本身的支持度再去考量,不是万能的准则。

    转载地址:http://xn--m8tz91bfdr2pjzo.xyz/%E8%A7%86%E5%9B%BE%E9%87%8D%E5%86%99%E5%92%8C%E7%AD%89%E4%BB%B7%E8%B0%93%E8%AF%8D%E9%87%8D%E5%86%99/?nsukey=chhBgRX3EAKcRyKGfljlqa%2F4ZT1MHm2KTgqwIPVs6ExhqY%2F6y74%2FP%2B9goM2K2jwZxsMU53GibSwJb8zhHntEFujtLAXR23huzT6M1QtAVrKex5yK6mINQ0pT%2Bh41oEE0GHi9IN0fEOLqNkF8hk4IENPpGHS1ToYPhzVG3ABrRP4PHT46CgqpS6MSjLfYZW%2B5

  • 相关阅读:
    SQL分页存储过程
    ASP.NET 程序优化
    SQL2005数据导入导出
    跨服务器修改表同时按照顺序关联两个没有关系的表
    SQL function中使用rand随机函数
    Ajax的一些体会
    XCode4 App Store提交小结
    XCode4 App Store提交小结
    wzplayer for mips成功面世,支持dlna,mms,http,rtsp
    tlplayer support smb
  • 原文地址:https://www.cnblogs.com/NoctisYang/p/8776279.html
Copyright © 2020-2023  润新知