SQL 语言支持的谓词表达式种类非常多,不同类型的谓词表达式估计选择率的方式也不相同。在 OceanBase 中,选择率的估计分成范围谓词的选择率估计和一般谓词的选择率估计两部分,优化器首先将谓词按照是否为范围谓词进行分类,两类谓词使用不同的方式计算,其中,所有的范围谓词作为一个整体估计,而一般谓词则逐个估计。
需要额外指出的是,如果谓词并不是直接作用于列数据,而是较为复杂的表达式,比如 log(column)+abs(column),优化器无法精确地估计其选择率,从而会采用默认的选择率进行估计(参见小节),在不特别说明的情况下,下文介绍的都是直接作用在列数据上的谓词。

等值谓词选择率

优化器基于表的行数、列的 NDV 以及列的 null 值数估计等值条件的选择率,它是其它类型谓词的选择率计算公式的基础,基于它可以推导出很多其它谓词选择率的计算公式。

如下是单列等值条件的 SQL 示例。

假设拥有如下信息:

  • 表 t1 的行数 num_rows = 10000

  • 列 c1 的 null 值数 num_nulls 为100

null值不可能满足谓词条件 c1 = 5 ,所以应从总行数中减去。优化器假设剩余的数据的值在其所有不同值上均匀分布,于是得到如下公式。

特别地,如果该列不存在null值,公式可以简化为“1 / ndv”。为了后续讨论方便,记 null 值率为 null 值的行数占总行数比。

谓词的选择率可以通过等值条件的选择率和 null 值率计算得到,具体公式如下:image

AND 谓词连接了两个子谓词。优化器缺省认为两个子谓词的选择率是相互独立的,它们的联合选择率是两者选择率的乘积。

对于互斥的两个谓词的 OR 谓词,只需将两个子谓词的选择率相加即可。

image

对于非互斥的 OR 谓词,优化器缺省认为两个子谓词是相互独立的。在将两个子谓词的选择率求和后,仍需要减去被重复累加的两个子谓词的联合选择率部分:

IN谓词的本质是一系列互斥的OR谓词,其每个子谓词都是一个等值谓词。只需将每个等值谓词的选择率相加即可。

如下是使用 NOT IN 谓词的示例。

范围谓词选择率

大于、大于等于、小于、小于等于等范围谓词实际上筛选出的是一系列值的区间,优化器会针对每一列抽取出这一类谓词,并将这一类谓词统一处理成一系列区间,并计算落在每一个区间内的选择率。
如下是两个范围谓词的示例。

如上示例对应了一个值的区间[33,100]。优化器缺省认为数值在整个 [min_value, max_value] 区间内的分布都是均匀的,于是优化器可以基于列的最大值和最小值,使用区间长度占比来计算选择率。需要注意的是,优化器还需要考虑到区间端点是否被包含,区间端点的选择率可以用等值谓词的选择率公式来计算,记区间包含的端点数为 N,可以得到以下公式。

c4ce0d4cccef70ef115fd653c43df412.svg

额外需要补充说明的是,考虑到存储层、SQL 层估计的准确性问题,对于最值的边界还会有一些相对特殊的处理,以保证在最值区间以外的区间仍会返回一个较少的默认行数。

LIKE 谓词选择率

LIKE谓词选择率对于形如LIKE “A\_STRING%”的 LIKE 谓词,它实际上也对应了一个范围,同样可以通过和范围谓词选择率一样的计算方式得到,优化器会将区间长度的计算修改成相应的字符串版本。对于形如LIKE“%A\_STRING”的 LIKE 谓词,由于位于头部的通配符实际上无法限定范围,优化器会选择一个默认的选择率。

默认选择率

默认选择率在谓词条件、连接条件过于复杂、无法精确估算选择率,或者估算选择率依赖的统计信息缺失时,优化器会使用默认的选择率进行选择率的估计。

JOIN 连接条件选择率估计

非等值连接选择率

对于非等值连接的选择率,优化器会将这些连接条件当做普通的单表谓词来进行计算选择率。

等值连接选择率

等值连接的连接条件和等值谓词条件基本一致,可以将其看成两张表进行笛卡尔乘积之后的新表的一个等值谓词条件。在新生成的大表中,某一表中不存在的值将不存在,新表的选择率实际上由小表限制。优化器选择两表选择率中较小的一个作为等值连接的选择率。