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