加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – SQL Server – LIKE运算符的基数估计(局部变量)

发布时间:2021-03-31 20:38:09 所属栏目:编程 来源:网络整理
导读:我的印象是,在全部针对未知场景的优化中行使LIKE运算符时,旧版CE和新CE都行使9%的预计值(假设相干统计信息可用且查询优化器不必告急于选择性揣摩).当对名誉数据库执行以下查询时,我在差异的CE下得到差异的预计.在新的CE下,我收到了900行的预计值,这是我祈望

我的印象是,在全部针对未知场景的优化中行使LIKE运算符时,旧版CE和新CE都行使9%的预计值(假设相干统计信息可用且查询优化器不必告急于选择性揣摩).当对名誉数据库执行以下查询时,我在差异的CE下得到差异的预计.在新的CE下,我收到了900行的预计值,这是我祈望的,在传统的CE下我收到的预计值为241.416,我无法弄清晰这个估算是怎样得出的.有人可以或许放弃任何光亮吗?

-- New CE (Estimate = 900)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName;

-- Forcing Legacy CE (Estimate = 241.416)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName
OPTION (
QUERYTRACEON 9481,QUERYTRACEON 9292,QUERYTRACEON 9204,QUERYTRACEON 3604
);

在我的场景中,我已经将名誉数据库配置为兼容级别120,因此为什么在第二个查询中我行使跟踪符号来逼迫传统CE而且还提供有关查询优化器行使/思量的统计信息的信息.我可以看到正在行使’lastname’的列统计信息,但我如故无法确定怎样推导出241.416的预计值.

除了this Itzik Ben-Gan article之外,我找不到任安在线内容,个中指出“当在全部优化中行使LIKE谓词用于未知场景时,旧版和新版CE都行使9%的预计值.”该帖子中的信息好像不正确.

办理要领

在您的环境下,LIKE的揣摩基于:

> G:尺度的9%揣摩(sqllang!x_Selectivity_Like)
> M:因子6(幻数)
> D:均匀数据长度(以字节为单元)(从统计数据),向下舍入为整数

详细来说,sqllang!CCardUtilSQL7 :: ProbLikeGuess行使:

Selectivity (S) = G / M * LOG(D)

条记:

>假如D在1和2之间,则省略LOG(D)项.
>假如D小于1(包罗丢失或NULL统计信息):
D = FLOOR(0.5 *最大列字节长度)

这种离奇和伟大性是原始CE的典范特性.

在题目示例中,均匀长度为5(来自DBCC SHOW_STATISTICS的5.6154向下舍入):

Estimate = 10,000 * (0.09 / 6 * LOG(5)) = 241.416

其他示例值:

 D  = Estimate using formula for S
 15 = 406.208
 14 = 395.859
 13 = 384.742
 12 = 372.736
 11 = 359.684
 10 = 345.388
 09 = 329.584
 08 = 311.916
 07 = 291.887
 06 = 268.764
 05 = 241.416
 04 = 207.944
 03 = 164.792
 02 = 150.000 (LOG not used)
 01 = 150.000 (LOG not used)
 00 = 291.887 (LOG 7) /* FLOOR(0.5 * 15) [15 since lastname is varchar(15)] */

试验台

DECLARE
    @CharLength integer = 5,-- Set length here
    @Counter integer = 1;

CREATE TABLE #T (c1 varchar(15) NULL);

-- Add 10,000 rows
SET NOCOUNT ON;
SET STATISTICS XML OFF;

BEGIN TRANSACTION;
WHILE @Counter <= 10000
BEGIN
    INSERT #T (c1) VALUES (REPLICATE('X',@CharLength));
    SET @Counter = @Counter + 1;
END;
COMMIT TRANSACTION;

SET NOCOUNT OFF;
SET STATISTICS XML ON;

-- Test query
DECLARE @Like varchar(15);
SELECT * FROM #T AS T 
WHERE T.c1 LIKE @Like;

DROP TABLE #T;

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读