SQL Server LIKE 查询的基数估计

Dha*_*ghe 5 sql-server like cardinality-estimates sql-server-2017

我在名为 AspNetUsers 的表的 LastName 列上创建了非聚集索引的统计直方图向量。

在此输入图像描述

如果我运行查询,因为SELECT * FROM dbo.AspNetUsers WHERE LastName = 'Baker'它返回 6 行作为估计行,因为Baker是步骤之一的RANGE_HI_KEY ,因此 EQ_ROWS 值是我的估计行数。同样,如果我运行查询SELECT * FROM dbo.AspNetUsers WHERE LastName = 'Bacilia',它会返回 1 行作为估计行,导致Bacilia落入“Baker”步长范围,因此该步长的AVG_RAGE_ROWS值是我的估计行数。

同样,根据我的理解,如果我执行查询,因为SELECT * FROM dbo.AspNetUsers WHERE LastName LIKE 'Ba%'它匹配 2 个步骤(BakerBatagoda),所以它应该返回 27 + 51 (RANGE_ROWS) + 6 + 4 (EQ_ROWS) = 88。但它返回 99 行作为估计。

此基数估计如何与 LIKE 查询一起使用?在执行 LIKE 查询时,它是否使用不同的公式来估计行数?

Mar*_*ith 4

在执行 LIKE 查询时,它是否使用不同的公式来估计行数?

是的。

我不太了解血淋淋的细节,但请参阅此处提到的“字符串摘要统计”

统计对象包含字符串摘要统计信息,以改进使用 LIKE 运算符的查询谓词的基数估计;例如,WHERE ProductName LIKE '%Bike'。字符串摘要统计信息与直方图分开存储,并且当统计对象的类型为 char、varchar、nchar、nvarchar、varchar(max)、nvarchar(max)、text 或 ntext 时,在统计对象的第一个键列上创建。

我没有您的样本数据,但只是尝试了一下player_overviews_unindexed网球运动员数据集。

直方图的相关部分是

 RANGE_HI_KEY    RANGE_ROWS     EQ_ROWS   DISTINCT_RANGE_ROWS   AVG_RANGE_ROWS
----------------------------------------------------------------------------------
       Aubone            40           4                    37         1.081081
        Baker            79          12                    60         1.316667
       Barker            71           6                    55         1.290909
       Barton            46           4                    25             1.84
        Bates            26           5                    20              1.3
       Becker            45           6                    35         1.285714
Run Code Online (Sandbox Code Playgroud)

统计数据仅明确显示该范围将包含至少 170 行 (12 + 71 + 6 + 46 + 4 + 26 + 5)。当考虑到结束范围时最多为 294。

  • 79 姓氏 > '欧波内' 和姓氏 < '贝克'
  • 12 姓氏 = '贝克'
  • 71 姓氏 > '贝克' 和姓氏 < '巴克'
  • 6 姓氏 = '巴克'
  • 46 姓氏 > '巴克' 和姓氏 < '巴顿'
  • 4 姓氏 = '巴顿'
  • 26 姓氏 > '巴顿' 和姓氏 < '贝茨'
  • 5 姓氏 = '贝茨'
  • 45 姓氏 > '贝茨' 和姓氏 < '贝克尔'

当我对last_name列建立索引时last_name LIKE N'Ba%',谓词被转换为索引查找last_name >= N'Ba' AND last_name < N'BB'和剩余谓词,但估计值不同。

  • 估计为last_name >= N'Ba' AND last_name < N'BB'180.525 行。
  • 估计为last_name LIKE N'Ba%'235.935 行
  • 估计为LEFT(last_name, 2) = 'Ba'171.317 行。
  • 实际返回的行数为 241 行。

因为它可能只是将 的值LEFT添加到最小值 170 上。AVG_RANGE_ROWS1.316667

当进行简单的索引范围查找时,它看起来只是查看结束直方图步骤的范围大小以及查询将选择的范围,并基于此进行一些插值。

last_name > 'Aubone' and last_name < 'Baker'所以直方图中有 79 行( RANGE_ROWS)。

在此输入图像描述

它估计77.6735这 79 行中的行将在该范围内< 'Ba',并且只有 1.3265 行在该范围内>= 'Ba'- 尽管实际上数字分别是3445

有很多姓氏的球员(Babcock、Bahrami、Baer、Backe、Baghdatis、7 * Baileys 等)都属于该范围,但它无法从直方图中知道这一点。

据推测,字符串摘要统计数据确实比仅从直方图中更好地捕获了分布。