通过重写冗余查询加速数据库查询
SQL数据库查询经常包含相同操作的重复。例如,在表中查找特定人员的条目可能涉及提取所有具有该人员名字的条目和所有具有该人员姓氏的条目,然后计算它们的交集。如果名字和姓氏搜索需要两次查询同一数据库表,这种冗余会增加检索时间。
在IEEE国际数据工程会议(ICDE)上发表的一篇论文中,我们描述了一种重写复杂SQL查询以消除此类冗余的方法。有时,这涉及检索条目的超集,然后根据附加条件进行筛选。但通常,检索后进行少量额外计算比多次查询同一表更高效。
查询重写技术
查询计划是执行SQL查询所需的一系列步骤。我们工作的重点是识别在重叠数据上计算的子查询,并将它们融合为单一计算,并通过补偿操作(检索后计算)重建原始结果。它不要求子查询在语法上相同或产生相同的输出。
以以下查询为例:
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块。这是次优的,特别是当重复计算代价高昂时。我们的技术可以识别此类模式并重写它们。例如,上述查询变为:
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是两个过滤条件,定义在P的输出列上,分别用于恢复P1和P2
Fuse是一个递归函数,可以处理不同的操作符,如表扫描、过滤器、投影、连接、聚合和去重聚合。
优化规则
我们引入了几个基于上述原语重写查询计划的优化规则:
GroupByJoinToWindow:此规则转换一个常见模式,其中表达式被聚合并连接回自身以获取聚合行的附加信息。
JoinOnKeys:此规则处理类似子查询(返回相同数据的不同视图)自连接的常见模式。
UnionAllOnJoin:此规则处理客户组合两个整体非常相似但仅在单个表上不同的计算结果场景。
UnionAll:此规则对应前面部分的示例查询。这是客户用于计算公共表达式然后合并具有不同投影的结果的非必然不相交子集的常见模式。
性能提升
在包含3TB数据的TPC-DS基准数据库实验中,我们的技术使99个查询的整体执行时间相比基线提高了14%。当仅限于被我们的重写规则直接转换的查询时,我们观察到性能提高了60%,某些查询执行速度提高了六倍以上。
这项工作中提出的技术已用于生产环境。值得注意的是,虽然某查询服务从中受益,但相同技术适用于其他数据库系统,因为它们不需要实现新的操作符或执行模型。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
1374

被折叠的 条评论
为什么被折叠?



