Tốt, xấu hoặc thờ ơ: WHERE 1 = 1


14

Đưa ra câu hỏi này trên reddit, tôi đã xóa sạch truy vấn để chỉ ra vấn đề nằm ở đâu trong truy vấn. Tôi sử dụng dấu phẩy trước và WHERE 1=1để sửa đổi các truy vấn dễ dàng hơn, vì vậy các truy vấn của tôi thường kết thúc như thế này:

SELECT 
     C.CompanyName
    ,O.ShippedDate
    ,OD.UnitPrice
    ,P.ProductName
FROM 
               Customers       as C
    INNER JOIN Orders          as O  ON C.CustomerID = O.CustomerID
    INNER JOIN [Order Details] as OD ON O.OrderID    = OD.OrderID
    INNER JOIN Products        as P  ON P.ProductID  = OD.ProductID
Where 1=1
--  AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
    And P.productname = 'TOFU'
Order By C.CompanyName

Về cơ bản, có người nói rằng 1 = 1 nói chung là lười biếng và không tốt cho hiệu suất .

Cho rằng tôi không muốn "tối ưu hóa sớm" - tôi thực sự muốn làm theo các thực hành tốt. Tôi đã xem xét các kế hoạch truy vấn trước đây, nhưng nói chung chỉ để tìm ra những chỉ mục nào tôi có thể thêm (hoặc điều chỉnh) để làm cho các truy vấn của tôi chạy nhanh hơn.

Câu hỏi sau đó thực sự ... có Where 1=1gây ra những điều xấu xảy ra không? Và nếu vậy, làm thế nào tôi có thể nói?

Chỉnh sửa nhỏ: Tôi luôn luôn 'giả định' cũng 1=1sẽ được tối ưu hóa, hoặc tệ nhất là không đáng kể. Không bao giờ đau lòng đặt câu hỏi về một câu thần chú, như "Goto's Evil" hoặc "Tối ưu hóa sớm ..." hoặc các sự kiện giả định khác. Không chắc chắn liệu 1=1 ANDcó thực sự ảnh hưởng đến kế hoạch truy vấn hay không. Còn trong các câu hỏi con thì sao? CTE? Thủ tục?

Tôi không phải là một người để tối ưu hóa, trừ khi cần thiết ... nhưng nếu tôi đang làm điều gì đó thực sự "xấu", tôi muốn giảm thiểu các hiệu ứng hoặc thay đổi khi áp dụng.


2
Không, nó sẽ không. Ngoài một vài micro giây cho trình tối ưu hóa để loại bỏ tình trạng dư thừa. Bạn nên tập trung vào ngày tháng của bạn theo nghĩa đen không mơ hồ.
ypercubeᵀᴹ

Như @ypercube đã nói, nó không có gì khác biệt. Trình tối ưu hóa truy vấn sẽ phải là một phần của **** cho một điều như vậy để tạo ra bất kỳ sự khác biệt nào;)
Phil

4
Đừng tin tất cả những gì bạn đọc trên reddit. Xin vui lòng.
Aaron Bertrand

1
@AaronBertrand Tôi lấy tất cả mọi thứ bằng một hạt muối, cho đến khi tôi trải nghiệm nó lần đầu tiên. Tôi vẫn sẽ đưa ra một câu hỏi nghe có vẻ hợp lý và xem liệu có bất kỳ sự thật nào với nó không, đặc biệt là khi nó ảnh hưởng đến công việc hàng ngày của tôi.
WernerCD

4
Có những hạt muối, sau đó có hàm lượng muối của cả một đại dương đổ trên đỉnh tòa nhà văn phòng của bạn: P
Philᵀᴹ

Câu trả lời:


13

Máy chủ SQL trình phân tích cú pháptrình tối ưu hóa có một tính năng gọi là "Constant Folding" giúp loại bỏ các biểu thức tautological khỏi truy vấn.
Nếu bạn nhìn vào kế hoạch thực hiện, không ở đâu trong các vị từ bạn sẽ thấy biểu thức đó xuất hiện. Điều này ngụ ý rằng việc gấp liên tục được thực hiện bằng mọi cách tại thời điểm biên dịch vì lý do này và các lý do khác và nó không ảnh hưởng đến hiệu suất truy vấn.

Xem Đánh giá xếp và biểu thức liên tục trong ước tính Cardinality để biết thêm thông tin.


Có lẽ nó được biên dịch đi vì đây là mô hình đã biết để thực hiện ghép các trường.
jcolebrand

Không, nó được biên dịch đi bởi vì nó là tautological. Nó sẽ hoạt động theo cùng một cách với 2736 = 2736, điều này không chỉ bình thường như 1 = 1. Điều tương tự cũng áp dụng cho các mâu thuẫn. Trong trường hợp đó, tính năng này được gọi là "Phát hiện mâu thuẫn".
spaghettidba

Phần nào của "mẫu đã biết" có nghĩa là "phải là 1 = 1"?
jcolebrand

9

Việc bổ sung vị từ dự phòng có thể tạo ra sự khác biệt trong SQL Server.

Trong các kế hoạch thực hiện dưới đây, hãy chú ý đến @1kế hoạch đầu tiên so với nghĩa đen 'foo'trong kế hoạch thứ hai.

nhập mô tả hình ảnh ở đây

Điều này chỉ ra rằng SQL Server đã xem xét truy vấn đầu tiên để tham số hóa đơn giản để thúc đẩy việc sử dụng lại kế hoạch thực hiện - tuy nhiên việc so sánh hai hằng số ngăn điều này xảy ra trong trường hợp thứ hai.

Có thể tìm thấy danh sách các điều kiện ngăn chặn tham số hóa đơn giản (trước đây gọi là tham số tự động) trong Phụ lục A của Kế hoạch bộ nhớ đệm kỹ thuật của Microsoft:

Mặc dù vậy, tham số đơn giản không phải là thứ mà bạn nên dựa vào. Nó là tốt hơn nhiều để tham số rõ ràng truy vấn của bạn.


4

Trong bất kỳ RDBMS hiện đại nào (bao gồm cả Oracle, Microsoft SQL Server và PostgreSQL - tôi chắc chắn về những điều này), điều này sẽ không ảnh hưởng đến hiệu suất.

Như ai đó đã lưu ý, điều này sẽ chỉ tác động đến giai đoạn lập kế hoạch truy vấn. Do đó, sự khác biệt sẽ chỉ hiển thị khi bạn chạy hàng ngàn lần lặp của truy vấn đơn giản không trả về bất kỳ dữ liệu nào, như thế này:

SELECT 1 FROM empty_table; -- run this 10 000 times.

SELECT 1 FROM empty_table WHERE 1=1; -- run this 10 000 times and compare.

Đối với tôi, trên PostgreSQL 9.0, điều này hiển thị chỉ với 10000 lần lặp:

filip@srv:~$ pgquerybench.pl -h /var/run/postgresql/ -q "select 1 from never where 1=1" -q "select 1 from never" -i 10000
Iterations: 10000
Query:   select 1 from never where 1=1
Total:   2.952 s
Average: 0.295 ms
Query:   select 1 from never
Total:   2.850 s
Average: 0.285 ms

0

Đây có thể là "vấn đề" đối với Oracle khi bạn sử dụng tham số cơ sở dữ liệu con trỏ. Khi điều này được đặt thành "bắt buộc", nó sẽ sửa đổi tất cả các câu lệnh SQL. Tất cả "hằng số" trong các truy vấn sẽ được thay thế bằng các biến liên kết (như 1 =>: SYS_0).

Tùy chọn này được giới thiệu để đối phó với một số nhà phát triển lười biếng. Mặt khác, nó cũng có thể gây hại cho các nhà phát triển lười biếng khác. Nhưng rủi ro không quá cao. Kể từ 11g nó có tính năng nhìn trộm biến.


Bạn có thể làm rõ những gì "Kể từ 11g, nó có tính năng nhìn trộm biến đổi." có nghĩa?
ypercubeᵀᴹ

@ypercube "Bind peeking peeking" có nghĩa là trình tối ưu hóa sẽ quan sát các giá trị thực của các biến liên kết và sử dụng số liệu thống kê dữ liệu để đánh giá lại và có thể tạo lại kế hoạch thực hiện truy vấn. Tôi nghi ngờ việc nhìn trộm sẽ có bất kỳ ảnh hưởng nào đến cấu trúc đang được thảo luận, vì nó không phụ thuộc vào thống kê dữ liệu.
mustaccio
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.