【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化

教材:王珊 萨师煊 编著 数据库系统概论(第5版) 高等教育出版社
注:文档高清截图在后

第9章 关系查询处理和查询优化

9.1 关系数据库系统的查询处理

1、RDBMS的查询处理分为四个阶段:
【1】查询分析。
对查询语句进行扫描、词法分析和语法分析,识别SQL关键字、属性名和关系名等语言符号,进行语法检查和分析,即判定查询语句是否合乎语法。若无语法错误,则转入下一步;否则,拒绝执行并报错。
【2】查询检查。
对合法语句进行语义检查,即根据数据字典中有关的模式定义检查语句中的数据库对象,如关系名、属性名是否存在且有效。如果是对视图的操作,则用视图消解方法把对视图的操作转换成对基本表的操作。还要根据数据字典中的用户权限和完整性约束定义对存取权限进行检查。如果用户无相应访问权限或违反完整性约束,就拒绝执行该查询。当然,这时的完整性检查是初步、静态的。检查通过后,SQL查询语句会被转换成等价的关系代数表达式,数据库对象的外部名称也被转换为内部表示。RDBMS一般都用查询树(query tree),也称语法树(syntax tree)来表示扩展的关系代数表达式。
【3】查询优化。
查询优化器通过综合运用各种优化技术,获得最好的查询速度提升效果。
【4】查询执行。
根据优化器得到的执行策略生成查询执行计划,由代码生成器(code generator)生成代码并执行,返回查询结果。

2、选择(select)操作的实现算法主要有:
【1】全表扫描(table scan)。
算法的步骤是:
(1)将一定数量的表的内容读入内存。
(2)检查内存的每个元组,输出满足条件的元组。
(3)如果未读取完毕,重复(1)(2)。
全表扫描算法只需要很少的内存(至少一个块。操作系统为了实现更先进的内存管理,一般都会将内存分成若干个块。物理内存被划分为一小块一小块,每块被称为帧(Frame)。分配内存时,帧是分配时的最小单位,最少也要给一帧。在逻辑内存中,与帧对应的概念就是页(Page)。)对规模小的表,这种算法既简单又有效。但表的元组数量较大且满足条件的元组数量占比较少时,顺序扫描的效率就很低。
【2】索引扫描(index scan)。
如果要求的条件中的属性上建立了索引(如B+树或Hash),可以用索引扫描方法,通过索引先找到满足条件的元组的指针,再通过指针访问基本表中的元组。
一般地,选择率较低时,基于索引的选择算法远远优于全表扫描算法。但在某些极端情形下,例如选择率很高,和/或要查找的元素十分均匀地分布,此时基于索引的选择算法的性能就不一定优于全表扫描。因为除了对表本身的扫描以外,对索引结构的操作和维护是需要额外的时间的。而且,根据索引而进行的访问,在内存空间中一般表现为无序。这种跳跃式的随机内存访问花费的时间显然要比顺序访问多出很多倍。

3、连接(join)操作是查询处理中最常用且最耗时的操作之一。这里简单介绍等值连接(自然连接)常用的几种思想。
【1】嵌套循环(nested loop)。
这是最简单可行的算法。类似于编程语言中的for循环,对若干个表通过这种暴力算法进行连接时,每一层循环查询一个元组时,都要重新检验其内层循环的全部元组是否能够与本层循环正在检验的元组构成符合连接的条件。
【2】排序-合并(归并排序,merge-sort)。
这也是等值连接的常用算法,尤其适合参与连接的各表已经有序的情况。
算法的步骤是:
(1)对参与连接的每一个表,如果未排序,都要将表进行排序。快排可以在O(n log n)的时间复杂度内完成排序。
(2)开始顺序扫描各个表,完成连接。所有参与连接的表都只需要扫描一次。表越大,通过归并排序执行的连接对执行时间的缩短越明显。
【3】索引连接(index join)。
以两张表的等值连接为例,通过索引连接算法进行等值连接,要求第二张表的包含在连接条件中的属性已建立索引。
算法的步骤是:
(1)对第一张表的每一个元组,通过索引查找第二张表中的相应元组。
(2)把这些元组连接起来。
重复执行上述两步,直到第一张表中的元组都处理完毕。
【4】哈希连接(Hash join)。
元组的连接属性被散列函数处理,然后将元组写入哈希表。哈希表采用桶(bucket)结构,相同哈希的元素被放入同一个桶。
算法的步骤是:
(1)划分阶段(building phase)。又称创建阶段。先对包含较少元组的表进行处理,将表的元组分散到哈希表的桶中。
(2)试探阶段(probing phase)。又称连接阶段。对剩余的表进行处理。将元组的连接属性进行哈希,然后找到适当的桶,与桶中匹配的元组连接起来。

9.2 关系数据库系统的查询优化

1、关系系统的查询优化既是关系数据库管理系统实现的关键技术,又是关系系统的优点所在。用户进行查询时,只需提出“干什么”,不必指出“怎么干”。对比一下非关系系统的情况:用户使用过程话的语言表达查询需求。执行何种操作,操作的序列等,这些都必须由用户自己决定。因此用户必须了解存取路径,还要制定存取策略。系统要提供用户选择存取路径的手段。查询效率受到用户水平的极大影响。如果用户做了不当的选择,系统也无法加以改进。
查询优化的优点不仅在于用户不必考虑如何最佳地表达查询以获得尽可能高的效率,而且系统常常可以比用户将查询优化得更好。这是因为:
【1】优化器可以从数据字典获得许多统计信息,例如元组数、属性值的分布、索引情况。优化器会根据这些信息做出正确估算,选择高效的执行计划。用户程序则难以获得这些信息。
【2】如果数据库的物理统计信息改变了,系统可以自动重新优化。在非关系系统中,用户必须重写程序。而将程序大幅度改动甚至推倒重做,在实际应用中往往因为工作量和开发周期等要求而不允许。
【3】优化器可以考虑大量的执行计划。而程序员一般只能有限地考虑几种可能性。
【4】优化器可以灵活运用多种复杂的优化技术。这些优化技术往往只有最好的程序员才能兼顾。由系统自动优化,相当于所有人都拥有了这些优化技术。

2、目前RDBMS通过数学模型计算各种查询执行策略的执行代价,选取代价最小的方案。集中式数据库中,查询开销主要包括IO代价、CPU代价和内存开销。对分布式数据库,还要计算通信代价。即:
总代价 = IO代价 + CPU代价 + 内存代价 + 通信代价。
如果数据库是采用机械硬盘作为磁盘,由于IO涉及机械动作,需要的时间将比内存操作高几个数量级。计算查询代价时,一般用读写的块数量作为衡量单位。
查询优化的搜索空间非常大,实际上系统的自动优化也不总是给出最优策略。

9.3 代数优化

1、代数优化也称逻辑优化,是指关系代数表达式的优化。代数优化策略是指通过关系代数表达式的等价变换提高查询效率。

2、常用的等价变换规则(证明略):
【1】连接、笛卡尔积的交换律:
设E1和E2是关系代数表达式,F是连接运算的条件,则:
E1×E2≡E2×E1
E1▷◁E2≡E2▷◁E1
E1▷F◁E2≡E2▷F◁E1
【2】连接、笛卡尔积的结合律:
(E1×E2)×E3≡E1×(E2×E3)
(E1▷◁E2)▷◁E3≡E1▷◁ (E2▷◁E3)
(E1▷F1◁E2)▷F2◁E3≡E1▷F1◁ (E2▷F2◁E3)
【3】投影的串接定律:
ΠA1, A2, …, An(ΠB1, B2, …, Bn (E))≡ΠA1, A2, …, An(E)
E是关系代数表达式,Ai(i = 1,2,……,n),Bj(j = 1,2,……,m)是属性名,且{A1, A2, …, An}是{B1, B2, …, Bm}的子集。
【4】选择的串接定律:
σF1(σF2(E))≡σF1∧F2(E)
E是关系代数表达式,F1、F2是选择的条件。该串接律说明对同一表达式的多个选择提出的要求可以合并,这样就可以一次性检查全部条件。
【5】选择与投影的交换律:
σF(ΠA1, A2, …, An(E))≡ΠA1, A2, …, An(σF(E))
这里要求选择条件F只涉及属性A1, A2, …, An。
如果F中有不属于A1, A2, …, An的属性B1, B2, …, Bn,则有更一般的规则:
ΠA1, A2, …, An(σF(E))≡ΠA1, A2, …, An(σF(ΠA1, A2, …, An, B1, B2, …, Bn(E)))
【6】选择与笛卡尔积的交换律:
如果F中涉及的属性都是E1中的属性,则
σF(E1×E2)≡σF(E1)×E2
如果F = F1∧F2,且F1、F2中涉及的属性分别都只是E1、E2的属性,则由等价变换规则1、4、6可推出
σF(E1×E2)≡σF1(E1)×σF2(E2)
如果F1、F2中涉及的属性分别都只是E1、E1和E2的属性,则仍有
σF(E1×E2)≡σF2(σF1(E1)×(E2))
【7】选择对并的分配律:
设E = E1∪E2,且E1和E2有相同的属性名,则
σF(E1∪E2)≡σF(E1)∪σF(E2)
【8】选择对差的分配律:
设E1和E2有相同的属性名,则
σF(E1 – E2)≡σF(E1) – σF(E2)
【9】选择对自然连接的分配律:
σF(E1▷◁E2)≡σF(E1)▷◁σF(E2)
F只涉及E1和E2的公共属性。
【10】投影对笛卡尔积的分配律:
设E1和E2是两个关系表达式,A1, A2, …, An和B1, B2, …, Bm分别是E1和E2的属性,则
ΠA1, A2, …, An, B1, B2, …, Bm(E1×E2)≡ΠA1, A2, …, An(E1)×ΠA1, A2, …, An, B1, B2, …, Bm(E2)
【11】投影对并的分配律:
设E1和E2有相同的属性名,则
ΠA1, A2, …, An, B1, B2, …, Bm(E1∪E2)≡ΠA1, A2, …, An(E1)∪ΠA1, A2, …, An, B1, B2, …, Bm(E2)
(注意:虽然笛卡尔积不满足交换律,但是关系表的属性是没有顺序的,因此即使交换笛卡尔积的两个操作数,得到的新表也视为同一张表)

3、基于启发式规则(heuristic rules)的代数优化是对关系代数表达式的查询树进行优化的方法。典型的启发式规则有:
【1】选择运算应尽可能先做。在优化策略中这是最重要、最基本的一条。因为先将符合一部分条件的元组单独选出来,从而令后续的操作可以都在这些先选出的符合条件的元组上进行,往往可以将代价节约几个数量级。
【2】投影和选择同时进行。如有若干投影和选择运算,且都对同一关系操作,则可以在扫描此关系的同时完成所有的这些运算,避免在分步进行这些投影和选择时反复扫描关系。
【3】把投影同其前后的双目运算结合起来。没有必要为了去掉某些字段而扫描一遍关系。
【4】把某些选择同在它之前要执行的笛卡尔积结合起来成为一个连接运算。连接(特别是等值连接)运算要比同样关系上的笛卡尔积节省很多时间。
【5】找出公共子表达式。如果某些表达式反复出现,且从外存中读入该关系比多次计算该子表达式的时间少,就应该先计算一次该表达式并将结果写入外存,然后在后续操作中直接引用这个结果而不要再计算该表达式。当查询的是视图时,定义视图的表达式就是公共子表达式的情况。

4、下面给出遵循上述启发式规则,且利用前面的等价变换公式来优化关系表达式的算法。
算法名称:关系表达式的优化。
输入:一个关系表达式的查询树。
输出:优化的查询树。
步骤:
【1】利用等价变换规则4:选择的串接定律,把形如σF1∧F2∧…∧Fn(E)的表达式变换成σF1(σF2(…(σFn(E))…))。
我们发现,对后者,从内层向外层计算时,每层都只需判定一个条件,而且得到的结果的元组数量总是减少(至少不变,不会增加)的。而变换之前的表达式需要对原有的大量的元组中的每一个元组都要判定n个条件。显然优化以后可以令查询速率大大提高。
【2】对每一个选择,利用等价变换规则4~9:选择的串接定律,选择与投影、笛卡尔积的交换律,选择对并、差、自然连接的分配律,尽可能将其移到叶节点。
【3】对每一个投影,利用等价变换规则3、5、10、11:投影的串接定律,选择与投影的交换律,投影对笛卡尔积和并的分配律,尽可能将其移到叶节点。
【4】利用等价变换规则3~5:投影和选择的串接定律,选择与投影的交换律,把选择和投影的串接合并成单个选择、单个投影,或一个选择后跟一个投影,使得多个选择和投影可以同时执行,或在一次扫描中全部完成。尽管这种变换似乎违背“投影尽可能早做”的原则,但这样做的效率更高。
【5】把上述得到的语法树的内节点分组。每一组双目运算(笛卡尔积、连接、并、差)和它所有的直接祖先(选择、投影)为一组。如果其后代直到树叶全部是单目运算,则也将它们并入该组。但当双目运算是笛卡尔积,而且后面不是与它组成的等值连接的选择时,不能把选择与这个双目运算组成同一组。把这些单目运算单独分一组。

9.4 物理优化

1、代数优化改变了查询语句的操作次序和组合,但不涉及底层操作和存取路径。对一个查询,可以有许多存取方案,它们执行效率不同,可以相差很大。因此仅仅进行代数优化是不够的。物理优化就是要选择高效合理的底层操作和存取路径,求得更优化的查询计划,达到查询优化的目标。

2、常用的优化方法:
【1】基于规则的启发式优化。启发式规则在多数情况下都使用,但不是每种情况下都是最好。
【2】基于代价估算的优化。优化器估算不同执行策略的代价,并选出代价最小的执行计划。
【3】两者结合。优化器通常把这两种技术结合使用。可能的执行策略极多,穷尽所有的策略进行代价估算一般是不可行的,因为会造成优化本身付出的代价大于收益。为此,禅茶和你关系先用启发式规则排除大部分不太优秀的方案,减少代价估算的工作量,再分别计算这些候选方案的执行代价,较快地选取最终的方案。

3、选择操作的启发式规则:
对于小关系,直接使用顺序扫描,即便选择的列上有索引。因为在特殊的数据结构上进行操作需要额外的时间,对规模很小的关系表,建立和维护这些数据结构以及在这些基础上查询所耗费的总时间反而大于直接顺序扫描。
对于大关系,启发式规则有:
【1】对选择条件是“主码 = 值”的查询,结果唯一,根据RDBMS自动为主码建立的索引查询。
【2】对选择条件是“非主属性 = 值”的查询,且选择列上有索引,则估算查询结果的元组数目。如果比例较多,不应使用索引,而是顺序扫描。
【3】对于选择条件是属性上的非等值查询或者范围查询,且选择列上有索引,仍然是估算查询结果的元组数目。如果比例较多,不应使用索引,而是顺序扫描。
【4】对于用AND连接的合取选择条件,如有涉及这些属性的组合索引,则优选组合索引扫描。如果某些属性上有一般索引,则有两种方法使用索引:第一种方法是,对每个属性的索引找出各自的元组指针,求交集,然后再到表中检索,输出结果。第二种方法是,对部分属性的索引找出各自的元组指针,先在表中索引,再检验未通过索引筛选的属性是否符合要求。同样,不应使用索引的情形中,应该全表扫描。
【5】对OR连接的析取选择条件,一般使用全表顺序扫描。

4、连接操作的启发式规则:
【1】如果部分表已经按照连接属性排序,一般应选择排序-合并算法。
【2】如果一个表在连接属性上存在索引,则可以考虑索引连接算法。
【3】如果上面两个规则都不适用,而有的表比其它表小得多,可以选用哈希连接算法。
【4】上述方法都不适用时,采用嵌套循环直接暴力求解。外循环应该选用占用内存的块数较小的表,理由如下:
设连接表R与S占用的块数分别为Br和Bs,连接需要消耗内存的块数为K,分配K – 1块给外表。如果R为外表,则嵌套循环法的存取块数(理论最大值)为:Br + BrBs / (K – 1)。显然应该选块数小的表作为外表。
上面列出的是主要的启发式规则。实际的RDBMS中,拥有的启发式规则的数量要多得多。

5、启发式规则优化是定性选择,比较粗糙,但实现简单且优化本身代价较小,适合解释执行的系统。因为解释执行的系统在读入语句时才当场进行语句的解析和执行,的优化开销包含在查询的总开销之中。在编译执行的系统中,语句先被编译为机器语言,以备日后反复执行。查询优化和查询执行是分开的,且一般而言这类系统执行的时间开销比编译要大得多。因此,可以采用精细复杂一些的基于代价的优化方法:
【1】基于统计信息的优化方法。
在数据字典中,存储了优化器需要的统计信息,包括:
(1)基本表的元组总数N、元组长度l、占用块数B、占用的溢出块数BO;
(2)基本表的每一列的不同的值的个数m、最大值、最小值、索引类型。根据这些信息可以计算出谓词条件的选择率f。如果不同值分布均匀,f = 1 / m;否则,需要计算每个值的选择率f = 具有该值的元组数 / N。
(3)索引的信息。以B+树为例,层数L、不同索引值的个数、索引的选择基数S(有S个元素具有某个索引值)、索引的叶节点数Y。
【2】基于公式的优化方法:
代价估算的常用公式:
(1)全表扫描的代价估算:
如果基本表大小为B块,则代价为B。
如果选择条件是“码 = 值”,平均搜索代价为B / 2。
(2)索引扫描的代价估算:
如果选择条件是“码 = 值”,且索引为B+树,层数为L,需要存取B+树中根节点到叶节点L块,再加上基本表中该元组占的一块,代价为L + 1。
如果选择条件涉及非码属性,若为B+树索引,选择条件是相等比较,S是索引的选择基数(S个元组满足条件)。因为满足条件的元组可能保存在不同的块上,所以最坏情况的代价是L + S。
如果比较条件是 > ,≥ ,< ,≤ ,设有一半元组满足条件,那么就要存取一半的叶节点,并通过索引访问一半的表存储块。所以代价为L + Y / 2 + B / 2。如果可以获得更准确的选择基数,则可以进一步修正Y / 2与B / 2。
(3)嵌套循环的代价估算:
嵌套循环连接算法的代价:Br + BrBs / (K – 1)。如果需要把连接结果写回磁盘,则代价为Br + BrBs / (K – 1) + (FrsNrNs) / Mrs。Frs为连接选择率(join selectivity),表示连接结果元组数的比例。Mrs是存放连接结果的块因子,表示每个块能存放的结果的元组数量。
(4)排序-合并连接算法的代价估算:
如果连接表已经按连接属性排序,则代价为Br + Bs + (FrsNrNs) / Mrs。
如果需要对文件排序,则需要增加排序的代价。对包含B个块的文件的排序代价约为2B + 2B log B。
实际的RDBMS中,代价估算公式要多得多、复杂得多。

6、语义优化,是指根据数据库的语义约束,把原先的查询转换成另一个执行效率更高的查询。
例如:如果根据约束条件检查到没有符合某个语句的查询结果,那么直接跳过该查询。

【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第1张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第2张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第3张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第4张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第5张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第6张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第7张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第8张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第9张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第10张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第11张图片【梳理】数据库系统概论 第9章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.2 关系数据库系统的查询优化 9.3 代数优化 9.4 物理优化_第12张图片

你可能感兴趣的:(基础课,#,数据库系统原理)