เหตุใด SQL Server จึงไม่มีคำขอดัชนีที่ขาดหายไปใน DMV หรือแผนการสืบค้น


14

ฉันมีฐานข้อมูล SQL Server ที่แบบสอบถามค่อนข้างช้าและมีการล็อคและบล็อกจำนวนมาก

เมื่อฉันดูดัชนี DMV ที่ขาดหายไปและแผนการสืบค้นไม่มีคำแนะนำใด ๆ

ทำไมถึงเป็นอย่างนั้น?

คำตอบ:


17

มีสาเหตุหลายประการที่ทำให้คุณไม่พลาดคำขอดัชนี!

เราจะดูรายละเอียดเพิ่มเติมด้วยเหตุผลสองสามข้อและพูดคุยเกี่ยวกับข้อ จำกัด ทั่วไปของคุณสมบัติ

ข้อ จำกัด ทั่วไป

ก่อนจาก: ข้อ จำกัด ของคุณสมบัติดัชนีที่ขาดหายไป :

  • มันไม่ได้ระบุคำสั่งสำหรับคอลัมน์ที่จะใช้ในดัชนี

ตามที่ระบุไว้ในคำถาม & คำตอบนี้: SQL Server จะกำหนดลำดับคอลัมน์คีย์อย่างไรในคำขอดัชนีที่ขาดหายไป ลำดับของคอลัมน์ในคำจำกัดความของดัชนีถูกกำหนดโดย Equality vs Inequality predicate จากนั้นตำแหน่งของคอลัมน์ในตาราง

ไม่มีการคาดเดาในการเลือกสรรและอาจมีคำสั่งที่ดีกว่า มันเป็นงานของคุณที่จะคิดออก

ดัชนีพิเศษ

คำขอดัชนีที่หายไปยังไม่ครอบคลุมดัชนี 'พิเศษ' เช่น:

  • พัว
  • กรอง
  • แบ่งพาร์ติชัน
  • การบีบอัด
  • XML-ED
  • Spatial-ED
  • columnstore-D
  • ดัชนีการดู -ed

มีการพิจารณาคอลัมน์อะไร

คอลัมน์คีย์ดัชนีที่หายไปนั้นสร้างขึ้นจากคอลัมน์ที่ใช้ในการกรองผลลัพธ์เช่นเดียวกับใน:

  • ร่วม
  • ประโยคที่

คอลัมน์ที่หายไปรวมดัชนีถูกสร้างขึ้นจากคอลัมน์ที่ต้องการโดยแบบสอบถามเช่นเดียวกับใน:

  • เลือก
  • จัดกลุ่มตาม
  • สั่งโดย

แม้ว่าคอลัมน์ค่อนข้างบ่อยคอลัมน์ที่คุณเรียงลำดับตามหรือจัดกลุ่มอาจมีประโยชน์เป็นคอลัมน์สำคัญได้ สิ่งนี้จะกลับไปเป็นข้อ จำกัด อย่างใดอย่างหนึ่ง:

  • มันไม่ได้มีวัตถุประสงค์เพื่อปรับแต่งการกำหนดค่าการจัดทำดัชนีอย่างละเอียด

ตัวอย่างเช่นแบบสอบถามนี้จะไม่ลงทะเบียนคำขอดัชนีที่ขาดหายไปแม้ว่าการเพิ่มดัชนีใน 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 ที่ขาดหายไป

SARGability

เพรดิเคตที่เครื่องมือเพิ่มประสิทธิภาพจะไม่สามารถใช้ดัชนีได้อย่างมีประสิทธิภาพแม้ว่าจะมีดัชนีอาจทำให้ไม่สามารถบันทึกได้

สิ่งที่ไม่ใช่ SARGable โดยทั่วไปคือ:

  • คอลัมน์ห่อในฟังก์ชั่น
  • คอลัมน์ + SomeValue = SomePredicate
  • คอลัมน์ + AnotherColumn = SomePredicate
  • คอลัมน์ = @Variable หรือ @Variable IS NULL

ตัวอย่าง:

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 จะเลือกสร้างดัชนีได้ทันทีผ่านดัชนีสปูล เมื่อสปูลดัชนีปรากฏขึ้นคำขอดัชนีที่หายไปจะไม่เป็นเช่นนั้น การเพิ่มดัชนีตัวเองอย่างแน่นอนอาจเป็นความคิดที่ดี แต่อย่านับบน SQL Server เพื่อช่วยให้คุณเข้าใจ

ถั่ว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.