Thứ tự mệnh đề where trong SQL có quan trọng không?


121

Giả sử tôi có một bảng được gọi là PEOPLEcó 3 cột ID, LastName, FirstName, không có cột nào trong số này được lập chỉ mục.
LastNameđộc đáo hơn và FirstNameít độc đáo hơn.

Nếu tôi thực hiện 2 tìm kiếm:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

Tôi tin rằng tiêu chí thứ hai nhanh hơn vì tiêu chí duy nhất ( LastName) đứng đầu trong wheremệnh đề và các bản ghi sẽ được loại bỏ hiệu quả hơn. Tôi không nghĩ trình tối ưu hóa đủ thông minh để tối ưu hóa sql đầu tiên.

Tôi hiểu có đúng không?


8
Không, trật tự mà không quan trọng - bất kỳ truy vấn tối ưu đàng hoàng sẽ xem xét tất cả các mệnh đề WHERE và con số ra cách hiệu quả nhất để đáp ứng truy vấn
marc_s

3
Bạn quan sát được gì khi chạy hai câu lệnh này? Các kế hoạch thực hiện trông như thế nào?
Conrad Frix,

3
Bạn đang đề cập đến một RDBMS cụ thể? Thực sự có sự khác biệt.
Bjoern


Câu trả lời:


101

Không, thứ tự đó không quan trọng (hoặc ít nhất: không quan trọng).

Bất kỳ trình tối ưu hóa truy vấn tốt nào sẽ xem xét tất cả các phần của WHEREmệnh đề và tìm ra cách hiệu quả nhất để đáp ứng truy vấn đó.

Tôi biết trình tối ưu hóa truy vấn SQL Server sẽ chọn một chỉ mục phù hợp - cho dù bạn có hai điều kiện của mình theo thứ tự nào. Tôi cho rằng các RDBMS khác sẽ có các chiến lược tương tự.

Điều quan trọng là bạn có một chỉ số phù hợp cho việc này hay không!

Trong trường hợp của SQL Server, nó có thể sẽ sử dụng một chỉ mục nếu bạn có:

  • một chỉ mục trên (LastName, FirstName)
  • một chỉ mục trên (FirstName, LastName)
  • một chỉ mục trên chỉ (LastName)hoặc chỉ (FirstName)(hoặc cả hai)

Mặt khác - một lần nữa đối với SQL Server - nếu bạn sử dụng SELECT *để lấy tất cả các cột từ một bảng và bảng khá nhỏ, thì rất có thể trình tối ưu hóa truy vấn sẽ chỉ quét bảng (hoặc chỉ mục theo cụm) thay vì sử dụng một chỉ mục (bởi vì việc tra cứu vào trang dữ liệu đầy đủ để lấy tất cả các cột khác rất nhanh chóng trở nên quá tốn kém).


Nếu không có (các) chỉ mục nào thì có thể đúng, tùy thuộc vào dữ liệu. Tất nhiên làm somnething như thế này mà không cần chỉ số, sẽ là một quyết định kỳ lạ ...
Tony Hopkinson

@TonyHopkinson: Tôi không nghĩ vậy - ngay cả khi không có chỉ mục, tôi vẫn nghi ngờ có bất kỳ sự khác biệt nào. Rốt cuộc: không có chỉ mục, thực sự thì RDBMS có thể làm được gì ngoài việc quét toàn bộ bảng không ??
marc_s

2
Lưu ý bên cạnh thú vị với máy chủ SQL, rõ ràng thứ tự KHÔNG TỒN TẠI
Justin Swartsel 11/12/12

3
Một điều kỳ lạ là đối với lần thực hiện đầu tiên của một truy vấn, thứ tự các điều kiện trong mệnh đề WHERE DOES MATTER! Tôi có hai điều kiện, đại loại như: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0và đã DIVIDE BY 0gặp lỗi. Sau khi tôi chuyển đổi thứ tự, các điều kiện truy vấn đã thực thi thành công. Sau đó, tôi chuyển lại lệnh nên tôi sẽ gặp lỗi một lần nữa, nhưng lần này nó đã hoạt động! Cuối cùng, kết luận của tôi là trong lần chạy đầu tiên, lệnh không quan trọng, cho đến khi kế hoạch thực hiện được xây dựng. 't vấn đề vì tôi ưu hoa / kế hoạch exec sẽ chăm sóc nó
Radu Gheorghiu

1
Tôi thích rằng bạn đã nói, "... hoặc ít nhất: không nên quan trọng" - Tôi hoàn toàn đồng ý. Đôi khi nó không quan trọng, thật không may. Tôi đã thấy các trường hợp SQL quá phức tạp để trình tối ưu hóa có thể xử lý và những thứ như thứ tự cột và thứ tự nối bảng đã tạo ra sự khác biệt. Nó phụ thuộc vào RDBMS, độ phức tạp của câu lệnh SQL và thậm chí cả bản phát hành. SQL rất phức tạp có thể dẫn đến các quyết định sai về trình tối ưu hóa hoặc sử dụng các giá trị mặc định được mã hóa cứng trong mã trình tối ưu hóa.
Victor Di Leo

19

Thứ tự của mệnh đề WHERE không được tạo ra sự khác biệt trong cơ sở dữ liệu tuân theo tiêu chuẩn SQL. Thứ tự đánh giá không được đảm bảo trong hầu hết các cơ sở dữ liệu.

Đừng nghĩ rằng SQL quan tâm đến thứ tự. Điều sau tạo ra lỗi trong SQL Server:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

Nếu phần đầu tiên của mệnh đề này được thực thi trước, thì chỉ các tên bảng số mới được chuyển thành số nguyên. Tuy nhiên, nó không thành công, cung cấp một ví dụ rõ ràng rằng SQL Server (cũng như các cơ sở dữ liệu khác) không quan tâm đến thứ tự của các mệnh đề trong câu lệnh WHERE.


Truy vấn gây ra lỗi đó có liên quan gì đến thứ tự đánh giá vị từ WHERE?
Jim,

7
@Jim Nếu ISNUMERIC(table_name) = 1được đánh giá đầu tiên, thì CASTsẽ chỉ được gọi cho các tên bảng số. Nhưng vì nó không được đánh giá trước nên CASTcũng được đánh giá cho các tên bảng không phải số, gây ra thông báo lỗi.
hibbelig

2
Làm rõ xuất sắc
neeohw

Chỉ để chắc chắn rằng tôi đã kiểm tra xem việc hoán đổi các điều kiện có khiến máy chủ SQL xử lý chúng theo cách khác hay không, nhưng nó không thành công cả hai cách. Tôi nghĩ điều này có thể có nghĩa là một trong hai điều: (1) Nó không tối ưu hóa tốt như nó có thể hoặc (2) Đó là một lỗi thời gian biên dịch và SQL thậm chí không bắt đầu thử so sánh bất kỳ thứ gì, loại trừ sơ bộ. Tôi đoán rằng đó là nr. 2.
Louis Somers

9

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 Trình tự đánh giá quy tắc

...

Khi mức độ ưu tiên không được xác định bởi Định dạng hoặc bằng dấu ngoặc đơn, việc đánh giá hiệu quả các biểu thức thường được thực hiện từ trái sang phải. Tuy nhiên, việc các biểu thức có thực sự được đánh giá từ trái sang phải hay không, đặc biệt khi các toán hạng hoặc toán tử có thể gây ra các điều kiện được nâng lên hoặc nếu kết quả của các biểu thức có thể được xác định mà không đánh giá hoàn toàn tất cả các phần của biểu thức.

sao chép từ đây


2

Không, tất cả các RDBM trước tiên đều bắt đầu bằng cách phân tích truy vấn và tối ưu hóa nó bằng cách sắp xếp lại mệnh đề where của bạn.

Tùy thuộc vào RDBM bạn đang sử dụng có thể hiển thị kết quả phân tích là gì (ví dụ: tìm kiếm kế hoạch giải thích trong oracle)

M.


Nó thực hiện điều đó dựa trên các chỉ mục. Vì vậy, nó gián tiếp về mặt nội dung.
Tony Hopkinson,

1

Tuyên bố OP gốc

Tôi tin rằng điều thứ hai là nhanh hơn vì tiêu chí duy nhất (LastName) đứng đầu tiên trong mệnh đề where và các bản ghi sẽ được loại bỏ hiệu quả hơn. Tôi không nghĩ trình tối ưu hóa> đủ thông minh để tối ưu hóa sql đầu tiên.

Tôi đoán bạn đang nhầm lẫn điều này với việc chọn thứ tự các cột trong khi tạo chỉ mục, nơi bạn phải đặt các cột chọn lọc hơn đầu tiên so với chọn lọc thứ hai, v.v.

BTW, đối với hai truy vấn trên, trình tối ưu hóa máy chủ SQL sẽ không thực hiện bất kỳ tối ưu hóa nào nhưng sẽ sử dụng gói Trivila miễn là tổng chi phí của gói nhỏ hơn chi phí ngưỡng song song.


0

Nó đúng khi nó đi, giả sử các tên không được lập chỉ mục. Dữ liệu khác nhau sẽ làm cho nó sai. Để tìm ra cách thực hiện, có thể khác nhau mọi lúc, DBMS sẽ phải chạy một truy vấn đếm riêng biệt cho từng cột và so sánh các con số, điều này sẽ tốn nhiều chi phí hơn là chỉ nhún vai và tiếp tục với nó.

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.