Maksimum belleği 25 GB olarak ayarlanmış bir SQL Server 2016 SP2'de, dakikada yaklaşık 80 kez çalışan bir sorgumuz var. Sorgu tempdb'ye yaklaşık 4000 sayfa döküyor. Bu tempdb diskinde çok sayıda IO'ya neden olur.
Bir baktığınızda sorgu planı (simplied sorgu) tahmini sıra sayısı fiili satır sayısına eşit olduğunu görürüz ancak yine de oluşur dökülen edeceğiz. Dolayısıyla, güncel olmayan istatistikler sorunun nedeni olamaz.
Tempdb için bazı test ve takip sorgu dökülmeleri yaptım:
select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Ancak farklı bir sütun seçersem dökülme olmaz:
select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Bu yüzden id sütununun boyutunu 'büyütmeye' çalıştım:
select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Sonra da dökülme meydana gelmez.
Benzersiz tanımlayıcı neden tempdb'ye dökülüyor ve bir veri zamanı sütunu değil? Yaklaşık 20000 kaydı sildiğimde, id sütununu seçtiğimde dökülme de olmaz.
Aşağıdaki komut dosyasıyla sorunu yeniden oluşturabilirsiniz:
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])