原文:《Preventing bad plans by bounding the impact of cardinality estimation errors》

摘要

  • 文章定义了一个衡量基数估计好坏的criterion:Q-error.

    • 对于我们给定的一个bound(边界),如果q-error小于bound,查询优化器将产生一个最佳计划。
    • 如果q-error以q为一个bound,那么我们就可以认为产生的执行计划最多比最佳计划差\(q^4\)倍。
  • 基于上述发现,文章展示了如何在q-error下找到最佳的近似值。
  • 这些技术可以用来构建基数估计synopsis(概要)

简介

  • 成本计算包括两方面:

    • 基数估计:对查询中间结果大小的估计,是成本计算的重点,往往会造成比较大的估计偏差而造成成本计算的错误。
    • 代数运算符的成本估计:多查询中进行的代数运算进行成本估计,往往估计的比较准确,与真实结果不到\(3\%\)的错误率。
  • 针对成本计算的现状提出了几个问题

    • Q1:基数估计总是出错,我们怎么衡量基数估计出现的错误大小?这个问题是最基本的问题
    • Q2A:如何最大限度的减少错误的传播
    • Q2B:是否存在一个对错误的边界,当错误在这个边界内,得到的执行计划仍然是最优计划,如果这个边界存在,它们具体是什么样的?
    • Q2C:如果最优计划\(P\)已知,而由查询优化器生成的计划为\(\hat{P}\),如果基数估计产生错误的bound我们已经知道,那么这个bound是否也可以约束\(\hat{P}\)和\(P\)之间的开销差距。也就是说,我们是否能通过基数估计产生的错误的边界而得到生成的执行计划与最优计划之间的差距?
    • Q3:我们如何最大限度的减少基数估计的错误?
  • 上述问题在本文中会得到逐一的解答。

q-error的定义

  • 首先对选择性估计问题进行了一个明确的定义

    • 有一个关系\(R\),\(A\)是\(R\)的一个属性。\({x_1,x_2,\cdots,x_m}=\Pi_A(R)\)是\(A\)的所有无重复取值。此时频率密度可以由一个对偶\(<x_i,f_i>\)集合表示,其中\(f_i=\{\sigma_{A=x_i}(R),i\in [1,m]\}\)。选择性估计的任务就是通过函数\(\hat{f}\)近似这组键值对,并将\(f\)映射到(0,1)。
  • 给出了q-error定义:

    • 在数学中,常用范数来进行误差分析,如果实际值用\(b\)向量表示,估算值用\(\hat{b}\)向量表示,用 p-范数计算的误差为:
    \[||b-\hat{b}||=\sqrt[p]{(b_i-\hat{b_i})^p}
    \]

    比较常用的是2-范数和\(\infty-\)范数,2-范数的结果是向量的长度,即向量各元素平方和再开方,\(\infty-\)范数是所有向量元素绝对值中的最大值。通过\(\infty-\)范数可以推导出估计值\(\hat{b}\)的上下界分别为\(b_i\)加减\(\infty-\)范数的值。但是绝对误差上界在查询优化中通常不是那么有用,文中定义了另一个误差函数q-error。

    • 首先给出q范数的定义:
      \[||z||_Q=\begin{cases}\infty \quad z\leq 0\\\frac{1}{z} \quad 0<z\leq 1\\z\quad 1\leq z\\\end{cases}
      \]
    • 对于一个向量\(z\):
    \[||z||_Q=\max_{i=1}^m||z_i||_Q=\max_{i=1}^m(\max{(z_i,\frac{1}{z_i})})
    \]
    • 对于估计值\(\hat{b}\)和真实值\(b\),我们将q-error定义为:
      \[||\frac{\hat{b}}{b}||_Q
      \]

      通过Q范数的定义形式,我们可以进一步推导得:

      \[q=||\frac{\hat{b}}{b}||_Q=\max_{i=1}^m(\max{(\frac{\hat{b_i}}{b_i},\frac{b_i}{\hat{b_i}})})
      \]
    • 类似于\(\infty\)范式,我们也能够确定一个基于Q范数估计值的边界:
    \[(\frac{1}{q})f_i\leq \hat{f_i}\leq qf_i
    \]

    到此我们了解了什么是 q-error 以及它的形式化定义,那为什么论文采用 q-error 来表示估算误差呢?在论文的第三部分我们会看到,我们可以通过最小化 q-error 来最小化估算误差的传播,q-error 也能帮我们解决 “是否存在一个误差上界,只要优化器的估算误差在这个上界以内就可以保证选到最佳执行计划?” 这个问题。

最小化q-error能最小化误差传播

《On the Propagation of Errors in the Size of Join Results》表明 selectivity 估算误差会在 join 节点上指数级的放大,如果用 q-error 来表示估算误差,join 结点对 selectivity 估算误差的放大效果是怎么样的呢?

  • 为了寻找 n 个表\(\{R_1,R_2,\cdots,R_N\}\)join 的最佳执行计划,我们需要先对每个表做 selectivity 估算,论文中假设了一个没有 join 条件(笛卡尔积)的简单场景,所有的过滤条件都推到了各个表上,这些表的 join 表示为\(\sigma_{p_1}(R_1)\Join \cdots\Join \sigma_{p_n}(R_n)\),令\(x\)表示这 n 个表的一个子集,这个子集里面 join 结果集的大小可以表示为:
\[s_x=(\prod_{R_i\in{x}}f_i)(\prod_{R_i\in{x},R_j\in{x}}(f_{i,j}))(\prod_{R_i\in{x}}|R_i|)
\]
  • 其中:

    • \(f_i\)表示\(\sigma_{p_i}(R_i)\)的真是selectivity
    • \(f_{i,j}\)表示表示第 i 和 j 个表 join 的真实 selectivity,如果没有 join 条件(笛卡尔积)则\(f_{i,j}=1\)
    • \(|R_i|\)表示第 i 个表的真实结果集大小
  • 可以通过先计算 k 个表 join 的结果集公式,再计算新增一个表(k+1 个表)的 join 结果集公式来得到上面 n 个表 join 的结果集大小计算公式。

我们用\(\hat{f_i}\)表示\(\sigma_{p_i}(R_i)\)的selectivity估算值,在假设量表join的selectivity估算值没有误差,以及各个表结果集大小的估算没有误差的情况下,可以通过上述计算公式得到这些表join结果集大小的估算值为:

\[\hat{s_x}=(\prod_{R_i\in{x}}\hat{f_i})(\prod_{R_i\in{x},R_j\in{x}}(f_{i,j}))(\prod_{R_i\in{x}}|R_i|)
\]

利用\(\prod_{R_i\in{x}}\frac{f_i}{f_i}=1\)的事实,我们可以给\(\hat{s_x}\)做一个等价变换:

\[\hat{s_x}=(\prod_{R_i\in{x}}\frac{f_i}{f_i})(\prod_{R_i\in{x}}\hat{f_i})(\prod_{R_i\in{x},R_j\in{x}}(f_{i,j}))(\prod_{R_i\in{x}}|R_i|)
\]
\[\hat{s_x}=(\prod_{R_i\in{x}}\frac{\hat{f_i}}{f_i})s_x
\]
\[\hat{s_x}\leq{(\prod_{R_i\in{x}}{\max(\frac{\hat{f_i}}{f_i},\frac{f_i}{\hat{f_i}})})s_x}
\]

而单个值的\(f_i\)和它的估计值\(\hat{f_i}\)的q-error可以表示成\(\max{(\frac{\hat{f_i}}{f_i},\frac{f_i}{\hat{f_i}})}\)。上面join集结果告诉我们:如果要最小化估算误差在 join 结点上的传播,我们需要最小化每个表上 selectivity 估算的 q-error。

  • 得到的结论似乎在预期之中,因为直觉告诉我们,不管估算误差用什么数学公式计算,只要我们能够最小化基表的估算误差,就一定对最小化 join selectivity 估算误差有帮助,上面的证明过程把这一直觉严谨的推演证明出来了,并且告诉了我们缩小估算误差的方式是缩小 q-error 而不是缩小绝对误差(∞-范数)。

  • 不过值得注意的是,要最小化 join 误差,我们还需要最小化两表 join selectivity 和各个表结果集大小的估算误差,分别是\(f_{i,j}\)和\(|R_i|\)

可以计算q-error界限,估计误差在此界限内的计划均为最优计划

确定一个选择性估计的偏离范围,使误差在此范围内不会影响最优执行计划的生成,换句话说q-error 的上界值应该是多少,使得只要优化器的估算误差在这个上界以内就可以保证选到最佳的执行计划?

论文分别就星型连接、链式连接以及普通的树形连接给出了相应的 q-error 上界计算公式。下面不等式的右边就是每个表 selectivity 估算误差的上界

  • 星型查询:
\[||\frac{f_k}{f_k'}||_Q\leq\min_{i\neq{j}}\sqrt{||\frac{f_if_{0,i}|R_i|}{f_jf_{0,j}|R_j|}||_Q}
\]
  • 链式查询:
\[||\frac{f_k'}{f_k}||_Q\leq\min_{i\neq{j-1}}\sqrt{||\frac{f_if_{i,i+1}|R_i|}{f_jf_{j,j-1}|R_j|}||_Q}
\]
  • 树型查询:
\[||\frac{f_k'}{f_k}||_Q\leq\min_{i\neq{j},R{i'}-R_i,R{j'}-R_j}\sqrt{||\frac{f_if_{i,i'}|R_i|}{f_jf_{j,j'}|R_i|}||_Q}
\]

q-error 上界能进一步推导出代价估算的误差上界

估算代价可以分为两步:selectivity 估算和代价估算。前者计算出某个算子会产生多少条数据,后者根据算子的物理实现,综合 CPU、内存、网络、磁盘以及刚才 “产生多少条数据” 等因素给出一个综合的代价值。论文的 “3.3 Cost Bounds Implied by Q” 部分通过推理,得到了一个结论:\(C(\hat{P})\leq q^4C(P)\),selectivity 估算误差上界可以推导出 cost 估算误差的上界。

如何设计 selectivity 估算函数使其低于误差上界

论文 “4. BEST APPROXIMATION UNDER LQ” 部分详细介绍了直方图桶内等值查询和范围查询的 selectivity 估算方法,如这章节开头所说 “This section makes heavy use of math“,因为数学公式比较多,看起来会吃力一些。

假设我们要估算一个过滤条件 where col = x 的 selectivity,经过数学建模和一系列的推导,论文提出使用线性函数\(\beta + \alpha x\)来拟合直方图桶内等值查询 selectivity 估算的方法,范围查询可以由等值查询推导而来。论文在 "4.2 Approximation Algorithm" 中给出了\(\alpha\)和\(\beta\)的计算方法,下图中 \(x_i\) 是采样值,\(b_i\) 是实际的 selectivity:

![[Pasted image 20211115190054.png]]

如何构造直方图

论文在 ”5.3 Piecewise Approximation“ 中简单描述了如何构造直方图。构造直方图比较难的地方是确定直方图每个桶的上下边界,比如等深直方图通过固定桶的数量和限制落在这个桶中的数据量一样多来计算每个桶的上下边界。在上面小结的计算过程中我们观察到,一个桶中的数据量越多,线性拟合的估算误差 q-error 就越大,这就给我们构造直方图每个桶的上下边界提供了指导思想。只要我们固定估算误差 q-error,就能够计算出落在每个桶中的数据有哪些(可以二分查找),进而得到每个桶的上下边界,构造出完整的直方图。论文中这里没有再详细描述,它给的参考文献可以读一读:《[Smooth Interpolating Histograms with Error Guarantees](download (psu.edu))》。

最后

这篇论文后面还有不少实验数据来验证线性拟合和其他估算方式的 q-error 对比,可以看到线性拟合的 q-error 确实能够限制在比较小的范围内。

总体上这篇论文对误差估算的建模分析是值得我们学习的,q-error 更是给我们如何衡量估算误差,如何降低估算误差指明了方向,这个的意义挺大的。

——觉得有帮助给笔者点个关注点个赞呀_

——参考https://zhuanlan.zhihu.com/p/165959743

限制q-error,防止产生次优计划的更多相关文章

  1. Postfix配置Q&A

    原文地址:http://space.doit.com.cn/51460/viewspace-4943.html 在配置Postfix中遇到的一些问题及相关的解决方法,希望在遇到相同的问题时能起参考的作 ...

  2. 执行计划sql

    我准备开始分析并优化我的查询.在分析之前,我想到了一些问题. MS-SQL Server什么时候使用"Table Scan"? MS-SQL Server什么时候使用"I ...

  3. sql server 数据库优化--显示执行计划

      刚开始用SQL Server的时候,我没有用显示执行计划来对查询进行分析.我曾经一直认为我递交的SQL查询都是最优的,而忽略了查询性能究竟如何,从而对“执行计划”重视不够.在我职业初期,我只要能获 ...

  4. 安装HomeBrew 失败的解决方案(Error: Fetching /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core failed!)

    在安装HomeBrew(或者安装成功 执行相关指令)时遇到错误提示: Error: Failure while executing: git clone https://github.com/Home ...

  5. Running MYSQL 5.7 By Bash On Ubuntu On Windows:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

    root@PC-RENGUOQIANG:/usr/sbin# /etc/init.d/mysql start * Starting MySQL database server mysqld [ OK ...

  6. mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记

    mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...

  7. Python开发入门与实战14-基于Extjs的界面

    14. 基于Extjs的界面 上一章我们实现了一个原生的html例子,本章我们将采用Extjs实现界面的展现,来说明MVC模式下我们是怎么考虑界面与业务层的关系的. 14.1. 引用Extjs目录 首 ...

  8. Python开发入门与实战13-基于模板的界面

    13. 基于模板的界面 本章我们将继续基于库存的简单例子来阐述如何在python django中体现MVC的架构,根据djangobook说明: M:数据存取部分,由django数据库层处理,本章要讲 ...

  9. VS2013使用rtklib中需要注意的一些问题(编译)

    最近因为项目需要需要对rtcm数据进行解码,rtklib提供了很多底层的函数,准备直接输出标准DLL的方式供C#调用.下面把项目中引用rtklib源码需要注意的地方记录下. 1. 首先在vs2013中 ...

随机推荐

  1. 自学 Python,视频教程和代码一看就懂,动手就废,应该这么学

    ​ 一.代码量太少了,看得多做得少,导致一做就错. 每一个测试工程师必定是在大量的时间和代码中提升的自己,如果你只是看视频的话,那永远都停留在理论上,很多问题是要实践才能发现的 我打个比方你看视频的时 ...

  2. 👊 Spring技术原理系列-从零开始教你SpringEL表达式使用和功能分析讲解指南(上篇)

    Spring EL表达式语言,这种语言jsp中学到的el,但是在整个spring之中其表达式语言要更加的复杂,而且支持度更加的广泛,最重要的是他可以进行方法的调用,对象的实例化,集合操作等等,但是唯一 ...

  3. 感恩笔记之SQL查询功能最简使用模板

    感恩笔记之SQL查询功能最简使用模板 第一部分:SQL单表功能 1 语句主要关键字 SELECT --查询数据列 INTO --新建数据表 FROM --查询数据表 WHERE --筛选数据表结果 O ...

  4. HBase基础

    Hadoop生态系统 HBase简介 HBase – Hadoop Database,是一个高可靠性.高性能.面向列.可伸缩.实时读写的分布式数据库 利用Hadoop HDFS作为其文件存储系统,利用 ...

  5. 【nvidia jetson xavier】 Deepstream Yolov3示例模型运行

    作者声明 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 原文链接:https://www.cnblogs.com/phoenixash/p/15 ...

  6. JVM详解(四)——运行时数据区-堆

    一.堆 1.介绍 Java运行程序对应一个进程,一个进程就对应一个JVM实例.一个JVM实例就有一个运行时数据区(Runtime),Runtime里面,就只有一个堆,一个方法区.这里也阐述了,方法区和 ...

  7. 3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项

    3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项 The diagram below shows the essential ...

  8. noj加1乘2平方

    广度优先搜索典例 00 题目 描述: 最简单的队列的使用#include <iostream>#include <queue>using namespace std;queue ...

  9. cs224n 2019

    视频链接 相关资源 Notes 笔记下载 笔记2 需要挂梯子,不然不显示图片,如果用ssr,要调到全局模式 转自:bitJoy CS224N(1.8)introduction and Word Vec ...

  10. django 中的hello word 开心,通过申请博客了,,发个随笔庆祝一下~~~~~~~

    django 中的hello word! 准备:[pymsql,pycharm,django3.0.7] >>>终端中:django-admin.py startproject [项 ...