Là hai truy vấn này tương đương logic?


10

Là hai truy vấn này tương đương logic?

DECLARE @DateTime DATETIME = GETDATE()

Truy vấn 1

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

Truy vấn 2

SELECT *
FROM   MyTable
WHERE  LogInsertTime < @DateTime - 7 

Nếu chúng không tương đương về mặt logic, bạn có thể cho tôi tương đương logic của truy vấn đầu tiên để mệnh đề WHERE có thể sử dụng hiệu quả một chỉ mục (nghĩa là loại bỏ chức năng gói) không?


Loại LogInsertTimegì?
dezso


LogInsertTime là một cơ sở dữ liệu
Alf47

Câu trả lời:


15

Cho dù hai truy vấn bạn đã đăng có tương đương về mặt logic hay không đều không liên quan; bạn không nên sử dụng một trong hai. Tôi sẽ cố gắng lèo lái bạn khỏi một vài điều:

  1. Bất cứ khi nào có thể, cố gắng tránh áp dụng các chức năng cho các cột. Luôn luôn tốt và tốt nhất là giữ các tính toán đó chống lại các hằng số chứ không phải các cột - điều này có thể phá hủy SARGability và khiến các chỉ mục trên các cột đó trở nên vô dụng. Trong trường hợp này, tôi rất thích truy vấn 2, đặc biệt nếu LogDateTimeđược lập chỉ mục (hoặc có thể là bao giờ).
  2. Tôi không thích môn toán ngày tháng tốc ký và tôi khuyên bạn nên chống lại nó. Chắc chắn, việc nhập nhanh hơn, nhưng hãy thử với DATEkiểu dữ liệu và bạn sẽ gặp một lỗi xấu. Tốt hơn nhiều để đánh vần nó, ví dụ:

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

Tôi đồng ý, mục tiêu của tôi là thay đổi truy vấn 1 thành một truy vấn tương tự như truy vấn 2 để các chỉ mục có thể được sử dụng một cách hiệu quả. Cảm ơn sự giúp đỡ của bạn
Alf47

8

Tôi sẽ sử dụng truy vấn có thể mở rộng sau đây:

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

Lý do: Tôi tin rằng kết quả của @ DateTime-7 không được ghi lại. Ngay cả khi nó chỉ tương đương với DATEADD (NGÀY, -7, @DateTime), nó có thể bị hỏng trong bản phát hành sau.


Thật tuyệt, đó chính xác là những gì tôi đang tìm kiếm, cảm ơn bạn
Alf47

2
Trên thực tế, đó là tài liệu và được xác định rõ : - (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date.. Tuy nhiên, tôi đồng ý rằng việc sử dụng các hàm ngày rõ ràng làm cho truy vấn kết quả dễ đọc và dễ duy trì hơn so với "phép toán toán học số học".
Heinzi

6

Chúng không tương đương. Các bản ghi cách đây 7 ngày, nhưng trước thời điểm hiện tại trong ngày - sẽ chỉ được trả về trong truy vấn # 2:

Khi so sánh ngày sử dụng DATEADDhàm , nó không xem xét phần thời gian . Hàm sẽ trả về 1 khi so sánh Chủ nhật & Thứ hai, bất kể thời gian.

Bản giới thiệu:

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.

Tương đương logic của truy vấn đầu tiên sẽ cho phép sử dụng chỉ mục tiềm năng là loại bỏ phần thời gian của @DateTimehoặc để đặt thời gian thành 0:00:00:

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

Lý do tại sao truy vấn đầu tiên không thể sử dụng một chỉ mục trên LogInsertTimelà vì cột được chôn trong một hàm. Truy vấn # 2 so sánh cột với giá trị không đổi cho phép trình tối ưu hóa chọn chỉ mục trên LogInsertTime.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.