Bu iki sorgu mantıksal olarak eşdeğer midir?


10

Bu iki sorgu mantıksal olarak eşdeğer midir?

DECLARE @DateTime DATETIME = GETDATE()

Sorgu 1

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

Sorgu 2

SELECT *
FROM   MyTable
WHERE  LogInsertTime < @DateTime - 7 

Mantıksal olarak eşdeğer değilse, WHERE yan tümcesinin etkili bir şekilde bir dizin kullanabilmesi için ilk sorgunun mantıksal eşdeğerini verebilir misiniz (yani işlev kaydırmayı ortadan kaldırabilir)?


Ne tür LogInsertTime?
dezso


LogInsertTime bir DATETIME
Alf47

Yanıtlar:


15

Gönderdiğiniz iki sorgunun mantıksal olarak eşdeğer olup olmadığı önemsizdir; ikisini de kullanmamalısınız. Sizi birkaç şeyden uzaklaştırmaya çalışacağım:

  1. Mümkün olduğunda sütunlara işlev uygulamaktan kaçının. Bu hesaplamaları sütunlara değil sabitlere karşı tutmak her zaman iyi ve çoğunlukla daha iyidir - bu SARGability'yi yok edebilir ve bu sütunlardaki dizinleri işe yaramaz hale getirebilir. Bu durumda, özellikleLogDateTime dizin 2 ise (veya hiç olabilir) sorgu 2'yi tercih ederim .
  2. Stenografi matematiğini sevmiyorum ve buna karşı öneriyorum. Elbette, yazmak daha hızlıdır, ancak bunu bir DATEveri türüyle deneyin ve çirkin bir hata alırsınız. Hecelemek çok daha iyi, örneğin:

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

Kabul ediyorum, amacım dizin 1 etkili bir şekilde kullanılabilir böylece sorgu 1 benzer bir şey içine değiştirmek oldu. Yardımınız için teşekkür ederiz
Alf47

8

Aşağıdaki sevimli sorgu kullanabilirsiniz:

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

Nedeni: @ DateTime-7'nin sonucunun belgelenmediğine inanıyorum. DATEADD (DAY, -7, @DateTime) ile eşdeğer olsa bile, daha sonraki bir sürümde bozulabilir.


Aradığım şey tam olarak harika, teşekkür ederim
Alf47

2
Aslında, bir belgelenmiş ve iyi tanımlanmış : - (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date.. Yine de, açık tarih işlevlerini kullanmanın, ortaya çıkan sorguyu "aritmetik işleç büyüsünden" daha okunabilir ve sürdürülebilir hale getirdiğini kabul ediyorum.
Heinzi

6

Eşdeğer değiller. 7 gün önce, ancak günün geçerli saatinden önce olan kayıtlar yalnızca # 2 numaralı sorguda döndürülür:

Kullanarak gün karşılaştırıldığında DATEADDfonksiyonu , bu dikkate zaman yer almaz . İşlev, pazar gününden Pazartesi gününe göre saatlerden bağımsız olarak 1 döndürecektir.

Demo:

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.

Potansiyel dizin kullanımını etkinleştirecek ilk sorgunun mantıksal eşdeğeri, ya zaman bölümünü kaldırmak ya da saati şu @DateTimeşekilde ayarlamaktır 0:00:00:

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

İlk sorgunun bir dizini kullanamamasının LogInsertTimenedeni, sütunun bir işlev içinde gömülü olmasıdır. Sorgu 2, sütunu, optimize edicinin üzerinde bir dizin seçmesini sağlayan sabit bir değerle karşılaştırır LogInsertTime.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.