Urutkan tumpahan ke tempdb tetapi baris yang diperkirakan sama dengan baris yang sebenarnya

14

Pada SQL Server 2016 SP2 dengan memori maks diatur ke 25GB kami memiliki permintaan yang mengeksekusi sekitar 80 kali dalam satu menit. Kueri tumpah sekitar 4000 halaman ke tempdb. Ini menyebabkan banyak IO pada disk tempdb.

Ketika Anda melihat pada rencana kueri (kueri tersederhanakan) Anda akan melihat bahwa jumlah baris yang diestimasi sama dengan jumlah baris aktual tetapi masih terjadi tumpahan. Jadi statistik yang kedaluwarsa tidak dapat menjadi penyebab masalah.

Saya melakukan beberapa pengujian dan mengikuti tumpahan kueri ke Tempdb:

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

Tetapi jika saya memilih kolom yang berbeda tidak ada tumpahan:

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

Jadi saya mencoba untuk 'memperbesar' ukuran kolom id:

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

Kemudian juga tidak ada tumpahan.

Mengapa pengidentifikasi unik tumpah ke tempdb dan kolom data tidak? Ketika saya menghapus sekitar 20.000 catatan maka tidak ada tumpahan yang terjadi ketika saya memilih kolom id.

Dengan skrip berikut, Anda dapat mereproduksi masalah:

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]) 
Frederik Vanderhaegen
sumber

Jawaban:

14

Aktifkan jejak jejak 7470.

PERBAIKI: Mengurutkan tumpahan operator ke tempdb di SQL Server 2012 atau SQL Server 2014 ketika perkiraan jumlah baris dan ukuran baris sudah benar

Seperti yang saya tulis dalam menjawab pertanyaan Rencana Kueri :

Bendera jejak ini mengoreksi kesalahan dalam perhitungan. Ini cukup aman untuk digunakan, dan menurut saya harus diaktifkan secara default. Perubahan dilindungi oleh tanda jejak hanya untuk menghindari perubahan rencana yang tidak terduga.

Paul White 9
sumber