原文:《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. SpringBoot 简易实现热搜邮件推送,妈妈再也不用担心我不了解国家大事了

    1.前言 上班的时候,无聊的时候,偶尔跑去百度看下热搜,所以就萌生出这种想法,通过邮件推送的方式实现效果,首先找到百度热搜的页面 热搜,话不多说,直接开干. 2.环境准备 因为是个SpringBoot ...

  2. C++: 基于四叉树数据结构的自适应网格(初探)

    C++: 基于四叉树数据结构的自适应网格 二叉树是一种典型的非线性存储数据结构,查找效率可以达到\(O(log_2N)\),同样,这类树状结构存在许多种变体,详细参考邓俊辉老师的<数据结构C++ ...

  3. 洛谷3163 CQOI2014危桥 (最大流)

    一开始想了一发费用流做法然后直接出负环了 首先,比较显然的思路就是对于原图中没有限制的边,对应的流量就是\(inf\),如果是危桥,那么流量就应该是\(2\). 由于存在两个起始点,我们考虑直接\(s ...

  4. 接口自动化-Python3+request上传文件,发送multipart/form-data编码

    1.安装requests_toolbelt   pip install requests-toolbelt 2.发送文件中的数据 from requests_toolbelt import Multi ...

  5. docker中Jenkins启动无法安装插件,版本过低

    一.问题现象: 使用docker启动jenkins,在jenkins启动后却无法安装jenkins的插件,一直提示安装失败且从log看到提示信息显示为需要升级jenkins的版本 二.原因分析: 在使 ...

  6. HttpServletResponse 入门

    继承体系 功能: 设置响应消息 1. 设置响应行 格式:HTTP/1.1 200 ok 设置状态码:setStatus(int sc) 2. 设置响应头:setHeader(String name, ...

  7. 【二食堂】Alpha - Scrum Meeting 8

    Scrum Meeting 8 例会时间:4.18 11:40 - 12:10 进度情况 组员 昨日进度 今日任务 李健 1. 实体的添加和关系的添加实现的有bug,柴博和刘阳进行了帮助issue 1 ...

  8. OO第四次博客作业--第四单元总结及课程总结

    一.总结第四单元两次作业的架构设计 1.1 第一次作业 类图如下: 为了突出类.接口.方法.属性.和参数之间的层次结构关系,我为 Class 和 Interface 和 Operation 分别建立了 ...

  9. Noip模拟37 2021.8.12

    T1 数列 真是考场上不是数学的乱推柿子,想定理,是数学的没想出来.. 比较悲伤... 列柿子不用动脑子,就是没有想出来$EXgcd$解不定方程,淦.. 解处一组解后利用比较显然的性质: $x+\fr ...

  10. 零基础入门Linux有什么好的学习方法吗?(超详细)

    本节旨在介绍对于初学者如何学习 Linux 的建议,在这里不具体分析Linux的学习节点只分析对于零基础的伙伴的学习方法.那么如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Li ...