指数退避CE

时间:2017-09-24 19:04:31

标签: sql-server sql-server-2016

我希望有人可以向我解释为什么SQL Server会给我一个与我预期不同的估计。

我的参考链接(http://sqlmag.com/database-development/optimization-tips-multiple-range-predicates-part-1

表格的25%有string = 'C',10%有number = 9。 25,000实际上有string = 'C' AND number = 9但是根据指数退避CE,估计的行数应该是50000.但是,我得到25000。

Execution Plan

测试脚本

SELECT keycol, string, number
FROM dbo.TStrNum
WHERE string = 'C' AND number = 9

统计

DBCC SHOW_STATISTICS

测试服务器:SQL Server 2016

兼容级别:130

示例数据生成脚本

我使用参考链接中提供的相同脚本进行测试。这是

SET NOCOUNT ON;

IF OBJECT_ID(N'dbo.GetNums', N'IF') IS NOT NULL DROP FUNCTION dbo.GetNums;
GO
CREATE FUNCTION dbo.GetNums(@low AS BIGINT, @high AS BIGINT) RETURNS TABLE
AS
RETURN
  WITH
    L0   AS (SELECT c FROM (SELECT 1 UNION ALL SELECT 1) AS D(c)),
    L1   AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
    L2   AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
    L3   AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
    L4   AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
    L5   AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
    Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
            FROM L5)
  SELECT TOP(@high - @low + 1) @low + rownum - 1 AS n
  FROM Nums
  ORDER BY rownum;
GO


IF OBJECT_ID(N'dbo.TStrNum', N'U') IS NOT NULL DROP TABLE dbo.TStrNum;

CREATE TABLE dbo.TStrNum
(
  keycol INT NOT NULL IDENTITY,
  string VARCHAR(10) NOT NULL,
  number INT         NOT NULL
);


INSERT INTO dbo.TStrNum WITH (TABLOCK) (string, number)
  SELECT
    CHAR(ASCII('A') + S.n) AS string,
    N.n AS number
  FROM dbo.GetNums(0, 3) AS S
    CROSS JOIN dbo.GetNums(1, 10) AS N
    CROSS JOIN dbo.GetNums(1, 25000) AS M;

-- Indexes
 CREATE UNIQUE CLUSTERED INDEX idx_str_num ON dbo.TStrNum(string, number, keycol);
    -- Indexes

-- Trigger creation of histogram on second index key
SELECT keycol, string, number
FROM dbo.TStrNum
WHERE number = 9 AND number % 2 = 0;


-- Update statistics with full scan
UPDATE STATISTICS dbo.TStrNum WITH FULLSCAN;
GO

0 个答案:

没有答案