数据库查询优化技术解析

本文介绍了一种通过重写冗余SQL查询来提升数据库性能的技术方法,在TPC-DS基准测试中实现14%的整体执行时间提升,详细解析了查询融合原理和优化规则实现机制。

通过重写冗余操作加速数据库查询

SQL数据库查询经常包含相同操作的重复执行。例如,在表中查找特定人员的记录可能涉及提取所有具有该人员名字的条目和所有具有该人员姓氏的条目,然后计算它们的交集。如果名字和姓氏搜索需要两次查询同一数据库表,这种冗余会增加检索时间。

在IEEE数据工程国际会议(ICDE)上发表的论文中,描述了一种重写复杂SQL查询以消除此类冗余的方法。有时,这涉及检索条目的超集,然后根据附加条件进行筛选。但通常来说,检索后进行的少量额外计算比多次查询同一表更高效。

查询执行性能提升

在包含3TB数据的TPC-DS基准数据库实验中,该技术使99个查询的整体执行时间相比基线提升了14%。对于直接通过重写规则转换的查询,性能提升了60%,部分查询执行速度提高了六倍以上。

查询重写技术原理

查询计划是用于执行查询的一系列步骤(如数据扫描和聚合)。查询计划优化是从大量可能方案中选择最高效查询计划的过程。

这项工作的重点是识别在重叠数据上计算的子查询,并将它们融合为具有补偿操作(检索后计算)的单一计算,以重建原始结果。它不要求子查询在语法上相同或产生相同输出。

以以下查询为例:

1
2
3
4
WITH cte as (...complex_subquery...)
SELECT customer_id FROM cte WHERE fname = 'John'
UNION ALL
SELECT customer_id FROM cte WHERE lname = 'Smith'

该查询在FROM子句中两次使用cte块。这种操作不是最优的,特别是当重复计算成本很高时。该技术可以识别此类模式并进行重写。重写后的查询变为:

1
2
3
4
WITH cte as (...complex_subquery...)
SELECT customer_id FROM cte, (VALUES (1), (2)) T(tag)
WHERE (fname = 'John' AND tag=1)
   OR (lname = 'Smith' AND tag=2)

重写规则构建模块

定义了用于新查询计划优化规则的基本原语。具体来说,定义了一个Fuse函数,该函数接受两个输入计划并返回⊥(当融合不可能时)或一个四元组融合结果。

如果Fuse(P1, P2) = (P, M, L, R),则:

  • P是结果融合计划
  • M是从P2的输出列到P的输出列的映射
  • L和R是两个过滤条件,分别用于恢复P1和P2

优化规则应用

引入了多个基于上述原语重写查询计划的优化规则:

GroupByJoinToWindow规则:转换表达式聚合并连接回自身以获取聚合行附加信息的常见模式。

JoinOnKeys规则:处理返回相同数据不同视图的相似子查询自连接在一起的常见模式。

UnionAllOnJoin规则:处理客户将两个非常相似但仅在单个表上不同的计算结果组合的场景。

UnionAll规则:对应前面示例查询中的模式,客户使用通用表达式然后合并结果的不同投影子集。

该技术已在生产环境中使用,虽然某中心Athena从中受益,但同样适用于其他数据库系统,因为它们不需要实现新的操作符或执行模型。客户因此能够更快运行查询,并通过减少数据扫描量来降低费用。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计