将溢出排序到tempdb,但估计的行等于实际的行


14

在最大内存设置为25GB的SQL Server 2016 SP2上,我们有一个查询,在一分钟内执行大约80次。该查询将大约4000页溢出到tempdb。这会在tempdb磁盘上导致大量IO。

当您查看查询计划(简化查询)时,您会看到估计的行数等于实际的行数,但仍然会发生溢出。因此,过时的统计信息不能成为问题的原因。

我做了一些测试,然后查询溢出到Tempdb:

select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)

但是,如果我选择其他列,则不会发生溢出:

select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

因此,我尝试“扩大” id列的大小:

select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

然后也不会发生溢出。

为什么uniqueidentifier不会溢出到tempdb和datatime列?当我删除大约20000条记录时,选择id列也不会发生溢出。

使用以下脚本,您可以重现该问题:

CREATE TABLE SortProblem
  (
     id             UNIQUEIDENTIFIER,
     startdate      DATETIME,
     sequencenumber BIGINT,
     status         VARCHAR(50),
     PRIMARY KEY CLUSTERED(id)
  )

SET nocount ON;

WITH nums(num)
     AS (SELECT TOP 103000 ROW_NUMBER()
                             OVER (
                               ORDER BY 1/0)
         FROM   sys.all_objects o1,
                sys.all_objects o2)
INSERT INTO SortProblem
SELECT newid(),
       DATEADD(millisecond, num, GETDATE()),
       num,
       CASE
         WHEN num <= 100000 THEN 'A'
         WHEN num <= 101000 THEN 'B'
         WHEN num <= 102000 THEN 'C'
         WHEN num <= 103000 THEN 'D'
       END
FROM   nums

CREATE NONCLUSTERED INDEX [IX_Status]
  ON [dbo].[SortProblem]([status] ASC)
  INCLUDE ([sequencenumber]) 

Answers:


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.