กระสอบทราย
ขณะที่การทำงานในบล็อกด้านคุณภาพPosts®ฉันมาข้ามบางพฤติกรรมเพิ่มประสิทธิภาพผมพบว่ามันโกรธที่น่าสนใจ ฉันไม่มีคำอธิบายในทันทีอย่างน้อยก็ไม่มีใครมีความสุขดังนั้นฉันวางไว้ที่นี่ในกรณีที่มีคนฉลาดปรากฏขึ้น
ถ้าคุณต้องการที่จะทำตามที่คุณสามารถคว้า 2013 รุ่นของการถ่ายโอนข้อมูลกองมากเกินที่นี่ ฉันใช้ตารางความคิดเห็นโดยมีดัชนีเพิ่มเติมหนึ่งรายการ
CREATE INDEX [ix_ennui] ON [dbo].[Comments] ( [UserId], [Score] DESC );
คำค้นหาหนึ่ง
เมื่อผมสอบถามตารางเช่นดังนั้นฉันได้รับแผนแบบสอบถามแปลก
WITH x
AS
(
SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
ORDER BY c.Score DESC
)
SELECT *
FROM x
WHERE x.Score >= 500;
เพรดิเคต SARGable บนคะแนนไม่ได้ถูกผลักเข้าไปใน CTE มันอยู่ในตัวดำเนินการตัวกรองในภายหลังในแผน
ซึ่งฉันพบว่าคี่เนื่องจากORDER BY
อยู่ในคอลัมน์เดียวกับตัวกรอง
แบบสอบถามสอง
ถ้าฉันเปลี่ยนแบบสอบถามมันจะถูกผลัก
WITH x
AS
(
SELECT c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
)
SELECT TOP 101 *
FROM x
WHERE x.Score >= 500
ORDER BY x.Score DESC;
เปลี่ยนแปลงแผนแบบสอบถามเกินไปและทำงานได้เร็วขึ้นมากกับการรั่วไหลไปยังดิสก์ไม่มี พวกเขาทั้งสองให้ผลลัพธ์ที่เหมือนกันพร้อมกับเพรดิเคตที่การสแกนดัชนีที่ไม่เป็นคลัสเตอร์
ข้อความค้นหาสาม
นี่คือเทียบเท่ากับการเขียนแบบสอบถามเช่น:
SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
WHERE c.Score >= 500
ORDER BY c.Score DESC;
ข้อความค้นหาสี่
การใช้ตารางที่ได้รับจะได้รับแผนการสืบค้นที่ "ไม่ดี" เหมือนกับแบบสอบถาม CTE เริ่มต้น
SELECT *
FROM ( SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
ORDER BY c.Score DESC ) AS x
WHERE x.Score >= 500;
สิ่งต่าง ๆ แม้จะแปลกเมื่อ ...
<=
ฉันจะเปลี่ยนแบบสอบถามเพื่อสั่งซื้อจากน้อยไปมากข้อมูลและตัวกรองเพื่อ
เพื่อไม่ให้คำถามนี้ยาวเกินไปฉันจะรวบรวมทุกอย่างเข้าด้วยกัน
แบบสอบถาม
--Derived table
SELECT *
FROM ( SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
ORDER BY c.Score ASC ) AS x
WHERE x.Score <= 500;
--TOP inside CTE
WITH x
AS
(
SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
ORDER BY c.Score ASC
)
SELECT *
FROM x
WHERE x.Score <= 500;
--Written normally
SELECT TOP 101
c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
WHERE c.Score <= 500
ORDER BY c.Score ASC;
--TOP outside CTE
WITH x
AS
(
SELECT c.UserId, c.Text, c.Score
FROM dbo.Comments AS c
)
SELECT TOP 101 *
FROM x
WHERE x.Score <= 500
ORDER BY x.Score ASC;
แผน
โปรดทราบว่าแบบสอบถามเหล่านี้ไม่ได้ใช้ประโยชน์จากดัชนีที่ไม่ได้จัดกลุ่ม - สิ่งเดียวที่เปลี่ยนแปลงได้ที่นี่คือตำแหน่งของผู้ดำเนินการตัวกรอง ไม่ว่าในกรณีใดคำกริยาจะถูกผลักไปยังการเข้าถึงดัชนี
คำถามปรากฏขึ้น!
มีเหตุผลหรือไม่ที่คำกริยา SARGable สามารถผลักได้ในบางสถานการณ์และไม่ใช่ในกรณีอื่น ๆ ? ความแตกต่างภายในเคียวรีที่เรียงลำดับจากมากไปน้อยเป็นสิ่งที่น่าสนใจ แต่ความแตกต่างระหว่างสิ่งเหล่านั้นกับสิ่งที่เรียงลำดับจากน้อยไปมาก
สำหรับผู้ที่สนใจนี่คือแผนการที่มีเพียงดัชนีในScore
: