แบบสอบถามทั้งสองนี้เทียบเท่ากันอย่างมีเหตุผลหรือไม่


10

แบบสอบถามทั้งสองนี้เทียบเท่ากันอย่างมีเหตุผลหรือไม่

DECLARE @DateTime DATETIME = GETDATE()

แบบสอบถาม 1

SELECT *
FROM   MyTable
WHERE  Datediff(DAY, LogInsertTime, @DateTime) > 7   

แบบสอบถาม 2

SELECT *
FROM   MyTable
WHERE  LogInsertTime < @DateTime - 7 

ถ้ามันไม่เท่ากันอย่างมีเหตุผลคุณช่วยให้ฉันมีเหตุผลเทียบเท่ากับการสืบค้นแรกเพื่อที่ WHERE clause สามารถใช้ดัชนีได้อย่างมีประสิทธิภาพ (เช่นกำจัดการตัดฟังก์ชั่น)?


ประเภทLogInsertTimeใด
dezso

1
ใช้เวลาดูknowdotnet.com/articles/getdatereturn.html
a1ex07

LogInsertTime เป็นเวลา DATETIME
Alf47

คำตอบ:


15

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

  1. เมื่อใดก็ตามที่เป็นไปได้พยายามหลีกเลี่ยงการใช้ฟังก์ชันกับคอลัมน์ มันดีเสมอและดีกว่าส่วนใหญ่ในการคงการคำนวณเหล่านั้นกับค่าคงที่และไม่ใช่คอลัมน์ - สิ่งนี้สามารถทำลาย SARGability และสร้างดัชนีในคอลัมน์เหล่านั้นได้โดยไร้ประโยชน์ ในกรณีนี้ฉันชอบแบบสอบถาม 2 มากโดยเฉพาะถ้าLogDateTimeมีการจัดทำดัชนี (หรืออาจเคย)
  2. ฉันไม่ชอบคณิตศาสตร์วันที่จดชวเลขและแนะนำให้เทียบกับมัน แน่นอนว่ามันเร็วกว่าในการพิมพ์ แต่ลองด้วยDATEประเภทข้อมูลและคุณจะได้รับข้อผิดพลาดที่น่าเกลียด ดีกว่ามากที่จะสะกดออกมาเช่น:

    WHERE LogInsertTime < DATEADD(DAY, -7, @DateTime);

ฉันเห็นด้วยเป้าหมายของฉันคือการเปลี่ยนแบบสอบถาม 1 เป็นสิ่งที่คล้ายกับแบบสอบถาม 2 เพื่อให้ดัชนีสามารถใช้อย่างมีประสิทธิภาพ ขอบคุณสำหรับความช่วยเหลือของคุณ
Alf47

8

ฉันจะใช้คำค้นหา sargeable ต่อไปนี้:

SELECT * FROM MyTable WHERE LogInsertTime < DATEADD(DAY, -7, @DateTime)

เหตุผล: ฉันเชื่อว่าผลลัพธ์ของ @ DateTime-7 ไม่ได้รับการบันทึกไว้ แม้ว่ามันจะเกิดขึ้นเทียบเท่ากับ DATEADD (DAY, -7, @DateTime) แต่มันอาจจะแตกหักในรุ่นต่อมา


เยี่ยมมากนั่นคือสิ่งที่ฉันกำลังมองหาขอบคุณ
Alf47

2
มันเป็นในความเป็นจริงการบันทึกและมีกำหนด- (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date. : ถึงกระนั้นฉันยอมรับว่าการใช้ฟังก์ชั่นวันที่ที่ชัดเจนทำให้การสืบค้นที่เป็นผลลัพธ์นั้นสามารถอ่านได้และสามารถบำรุงรักษาได้ดีกว่า "ผู้ดำเนินการทางคณิตศาสตร์"
Heinzi

6

พวกเขาจะไม่เทียบเท่า บันทึกที่ 7 วันที่ผ่านมา แต่ก่อนเวลาปัจจุบันของวัน - จะถูกส่งกลับในแบบสอบถาม # 2:

เมื่อเปรียบเทียบวันโดยใช้DATEADDฟังก์ชั่น , มันไม่ได้ใช้เวลาส่วนหนึ่งมาพิจารณา ฟังก์ชันจะส่งคืน 1 เมื่อเปรียบเทียบวันอาทิตย์และวันจันทร์โดยไม่คำนึงถึงเวลา

การสาธิต:

DECLARE @MyTable TABLE(pk INT, LogInsertTime DATETIME);

INSERT @MyTable
VALUES (1, DATEADD(HOUR, 1, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE))AS DATETIME))),
(2, DATEADD(HOUR, 23, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE)) AS DATETIME)));

DECLARE @DateTime DATETIME = GETDATE();

SELECT *
FROM @MyTable
WHERE DATEDIFF(DAY, LogInsertTime, @DateTime) > 7;

-- 0 records.

SELECT *
FROM @MyTable
WHERE LogInsertTime < @DateTime - 7;
-- 1 record.

ตรรกะเทียบเท่าของแบบสอบถามแรกที่จะช่วยให้การใช้ดัชนีที่มีศักยภาพคือการลบส่วนเวลา@DateTimeหรือเพื่อกำหนดเวลาไปที่0:00:00:

SELECT *
FROM @MyTable
WHERE LogInsertTime < CAST(@DateTime - 7 AS DATE);

สาเหตุที่แบบสอบถามแรกไม่สามารถใช้ดัชนีLogInsertTimeได้เนื่องจากคอลัมน์ถูกฝังอยู่ภายในฟังก์ชัน แบบสอบถาม # 2 LogInsertTimeเปรียบเทียบคอลัมน์เพื่อค่าคงที่ซึ่งจะช่วยเพิ่มประสิทธิภาพในการเลือกดัชนีบน

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