admin管理员组

文章数量:1660165

一、背景介绍
数据库优化器最重要的一个内容就是计算cardinality,因为cost model是要通过cardinality来的最后的cost的(当然很多cost model不好,就算cardinality准确,得到的cost也是错误的,这个在另外的专题再去讨论)。Cardinality是什么:给定predicate,满足这个predicate的tuple数量,predicate里包括查询条件和join。

传统计算cardinality方法是基于histogram,下面简单介绍一下什么是histogram。数据库的histogram一般是基于列的统计,也就是说每一列都有一个histogram。如下图1是列f的histogram,列f一共有14个唯一值0~14(注意,10是没有的),平均分为了5个区间(每个区间称之为bin)[0,2],[3,5],[6,8],[9,11],[12,14]。每个区间对应了#records,即这个区间有多少个records,在每个区间内的分布为均匀分布。

图1 列f的histogram
如果我们要计算predicate(f=1)的cardinality,那么在histogram查一下f=1对应的bin平均包含了3条记录,则输出cardinality为3;如果计算predicate(f=12)的cardinality,定位到第5个bin,平均包含5个record,则输出cardinality为5,而实际为2,这个就是histogram的误差。

二、Sampling方法
本文是要介绍sampling计算cardinality,那么具体怎么做呢?简单的方法就是在f列上随机sample 100个记录,看一下符合predicate有几个,假如有4个,那么符合predicate的概率为4/100,而f一共包含了1,000,000条记录,那么cardinality的结果为4/100*1,000,000=40000。

上面是单表(不包含join)的情况算起来很简单,实际上sampling主要用来处理有join的cardinality的估计,也就是去算join size的大小。比如先在A表上sample 100个records,B表上也sample 100个records,再针对sample结果做join,符合join条件的有4个records,即比率为4/100,那么A表1,000,000大小(假设B表也100万大小)情况下,join size为40000。

本文标签: 直方图基数方法estimatecardinality