บน SQL Server 2016 SP2 ที่มีหน่วยความจำสูงสุดตั้งไว้ที่ 25GB เรามีแบบสอบถามที่ดำเนินการประมาณ 80 ครั้งในหนึ่งนาที แบบสอบถามรั่วไหลประมาณ 4,000 หน้าไปยัง tempdb ซึ่งทำให้ IO จำนวนมากบนดิสก์ของ tempdb
เมื่อคุณดูที่แผนแบบสอบถาม (แบบสอบถามแบบง่าย) คุณจะเห็นว่าจำนวนแถวโดยประมาณเท่ากับจำนวนแถวจริง แต่ยังคงเกิดการรั่วไหล ดังนั้นสถิติที่ล้าสมัยไม่สามารถเป็นสาเหตุของปัญหาได้
ฉันทำการทดสอบและแบบสอบถามต่อไปนี้รั่วไหลไปยัง 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)
จากนั้นยังไม่มีการหกเกิดขึ้น
ทำไมตัวระบุที่ไม่ซ้ำกันหกถึง tempdb และคอลัมน์ข้อมูลไม่ เมื่อฉันลบประมาณ 20,000 บันทึกแล้วยังไม่มีการหกเกิดขึ้นเมื่อฉันเลือกคอลัมน์ 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])