ฉันมีฐานข้อมูล SQL Server ที่แบบสอบถามค่อนข้างช้าและมีการล็อคและบล็อกจำนวนมาก
เมื่อฉันดูดัชนี DMV ที่ขาดหายไปและแผนการสืบค้นไม่มีคำแนะนำใด ๆ
ทำไมถึงเป็นอย่างนั้น?
ฉันมีฐานข้อมูล SQL Server ที่แบบสอบถามค่อนข้างช้าและมีการล็อคและบล็อกจำนวนมาก
เมื่อฉันดูดัชนี DMV ที่ขาดหายไปและแผนการสืบค้นไม่มีคำแนะนำใด ๆ
ทำไมถึงเป็นอย่างนั้น?
คำตอบ:
เราจะดูรายละเอียดเพิ่มเติมด้วยเหตุผลสองสามข้อและพูดคุยเกี่ยวกับข้อ จำกัด ทั่วไปของคุณสมบัติ
ก่อนจาก: ข้อ จำกัด ของคุณสมบัติดัชนีที่ขาดหายไป :
- มันไม่ได้ระบุคำสั่งสำหรับคอลัมน์ที่จะใช้ในดัชนี
ตามที่ระบุไว้ในคำถาม & คำตอบนี้: SQL Server จะกำหนดลำดับคอลัมน์คีย์อย่างไรในคำขอดัชนีที่ขาดหายไป ลำดับของคอลัมน์ในคำจำกัดความของดัชนีถูกกำหนดโดย Equality vs Inequality predicate จากนั้นตำแหน่งของคอลัมน์ในตาราง
ไม่มีการคาดเดาในการเลือกสรรและอาจมีคำสั่งที่ดีกว่า มันเป็นงานของคุณที่จะคิดออก
ดัชนีพิเศษ
คำขอดัชนีที่หายไปยังไม่ครอบคลุมดัชนี 'พิเศษ' เช่น:
คอลัมน์คีย์ดัชนีที่หายไปนั้นสร้างขึ้นจากคอลัมน์ที่ใช้ในการกรองผลลัพธ์เช่นเดียวกับใน:
คอลัมน์ที่หายไปรวมดัชนีถูกสร้างขึ้นจากคอลัมน์ที่ต้องการโดยแบบสอบถามเช่นเดียวกับใน:
แม้ว่าคอลัมน์ค่อนข้างบ่อยคอลัมน์ที่คุณเรียงลำดับตามหรือจัดกลุ่มอาจมีประโยชน์เป็นคอลัมน์สำคัญได้ สิ่งนี้จะกลับไปเป็นข้อ จำกัด อย่างใดอย่างหนึ่ง:
- มันไม่ได้มีวัตถุประสงค์เพื่อปรับแต่งการกำหนดค่าการจัดทำดัชนีอย่างละเอียด
ตัวอย่างเช่นแบบสอบถามนี้จะไม่ลงทะเบียนคำขอดัชนีที่ขาดหายไปแม้ว่าการเพิ่มดัชนีใน LastAccessDate จะป้องกันไม่ให้ต้องเรียงลำดับ (และหกลงในดิสก์)
SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;
ไม่จัดกลุ่มแบบสอบถามนี้ในตำแหน่งที่ตั้ง
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
ใช่ แต่มันก็ยังดีกว่าไม่มีอะไร คิดว่าการร้องขอดัชนีที่ขาดหายไปเหมือนเด็กร้องไห้ คุณรู้ว่ามีปัญหา แต่มันขึ้นอยู่กับคุณในฐานะผู้ใหญ่ที่จะรู้ว่าปัญหานั้นคืออะไร
ผ่อนคลาย Bucko เราไปถึงที่นั่น
หากคุณเปิดใช้งานTF 2330คำขอดัชนีหายไปจะไม่ถูกบันทึก หากต้องการทราบว่าคุณเปิดใช้งานสิ่งนี้หรือไม่ให้เรียกใช้สิ่งนี้:
DBCC TRACESTATUS;
การสร้างดัชนีใหม่จะล้างคำขอดัชนีที่ขาดหายไป ดังนั้นก่อนที่คุณจะไป Hi-Ho-Silver-Away จะสร้างดัชนีใหม่ทุกวินาทีที่วินาทีของการกระจายตัวของเศษเล็กเศษน้อยย่องเข้าไปคิดเกี่ยวกับข้อมูลที่คุณล้างออกทุกครั้งที่คุณทำเช่นนั้น
นอกจากนี้คุณยังอาจต้องการที่จะคิดเกี่ยวกับทำไมจัดเรียงข้อมูลดัชนีของคุณไม่ได้ช่วยให้อยู่แล้ว ถ้าคุณกำลังใช้columnstore
การเพิ่มลบหรือปิดการใช้งานดัชนีจะล้างการร้องขอดัชนีที่หายไปทั้งหมดสำหรับตารางนั้น หากคุณกำลังทำงานกับการเปลี่ยนแปลงดัชนีหลายรายการในตารางเดียวกันตรวจสอบให้แน่ใจว่าคุณสคริปต์พวกเขาทั้งหมดก่อนที่จะทำการใด ๆ
หากแผนนั้นง่ายพอและตัวเลือกการเข้าถึงดัชนีนั้นชัดเจนเพียงพอและค่าใช้จ่ายต่ำพอคุณจะได้รับแผนการที่ไม่สำคัญ
ซึ่งหมายความว่าไม่มีการตัดสินใจที่คุ้มค่าสำหรับเครื่องมือเพิ่มประสิทธิภาพในการทำ
Via Paul White :
รายละเอียดของชนิดของแบบสอบถามที่ได้รับประโยชน์จาก Trivial Plan มีการเปลี่ยนแปลงบ่อยครั้ง แต่สิ่งต่าง ๆ เช่นการเชื่อมต่อแบบสอบถามย่อยและความไม่เท่าเทียมกันจะแสดงโดยทั่วไปจะป้องกันการเพิ่มประสิทธิภาพนี้
เมื่อแผนไม่ได้เป็นเรื่องขั้นตอนการเพิ่มประสิทธิภาพเพิ่มเติมจะไม่ได้สำรวจและจัดทำดัชนีที่หายไปจะไม่ได้รับการร้องขอ
ดูความแตกต่างระหว่างข้อความค้นหาเหล่านี้และแผนของพวกเขา :
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);
แผนแรกนั้นเล็กน้อยและไม่มีการร้องขอใด ๆ ปรากฏขึ้น อาจมีบางกรณีที่ข้อบกพร่องป้องกันดัชนีที่หายไปไม่ให้ปรากฏในแผนแบบสอบถาม พวกเขามักจะถูกบันทึกไว้อย่างน่าเชื่อถือมากขึ้นในดัชนี DMV ที่ขาดหายไป
เพรดิเคตที่เครื่องมือเพิ่มประสิทธิภาพจะไม่สามารถใช้ดัชนีได้อย่างมีประสิทธิภาพแม้ว่าจะมีดัชนีอาจทำให้ไม่สามารถบันทึกได้
สิ่งที่ไม่ใช่ SARGable โดยทั่วไปคือ:
SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
แบบสอบถามเหล่านี้จะไม่มีการลงทะเบียนคำขอดัชนีที่ขาดหายไป สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งเหล่านี้ตรวจสอบลิงค์ต่อไปนี้:
รับดัชนีนี้:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
ดูเหมือนว่าโอเคสำหรับคำถามนี้:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
แผนคือการแสวงหาง่าย ...
แต่เนื่องจากคอลัมน์คีย์หลักสำหรับเพรดิเคตที่เลือกน้อยเราจึงต้องทำงานมากกว่าที่เราควรจะ:
ตาราง 'โพสต์' สแกนนับ 13, ตรรกะอ่าน 136890
หากเราเปลี่ยนลำดับคอลัมน์ดัชนีคีย์เราจะทำงานให้น้อยลงมาก:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
และอ่านน้อยลงอย่างมาก:
ตาราง 'โพสต์' จำนวนการสแกน 1, ตรรกะอ่าน 5
ในบางกรณี SQL Server จะเลือกสร้างดัชนีได้ทันทีผ่านดัชนีสปูล เมื่อสปูลดัชนีปรากฏขึ้นคำขอดัชนีที่หายไปจะไม่เป็นเช่นนั้น การเพิ่มดัชนีตัวเองอย่างแน่นอนอาจเป็นความคิดที่ดี แต่อย่านับบน SQL Server เพื่อช่วยให้คุณเข้าใจ