2009-04-28 31 views
181

Theo định nghĩa (ít nhất là từ những gì tôi đã nhìn thấy) sargable có nghĩa là một truy vấn có khả năng có công cụ truy vấn tối ưu hóa kế hoạch thực hiện truy vấn sử dụng. Tôi đã cố gắng tìm kiếm các câu trả lời, nhưng dường như không có nhiều vấn đề. Vì vậy, câu hỏi là, những gì hiện hoặc không làm cho một truy vấn SQL sargable? Mọi tài liệu sẽ được đánh giá cao.Điều gì làm cho một câu lệnh SQL sargable?

Để tham khảo: Sargable

+41

+1 cho "sargable". Đó là lời của tôi trong ngày hôm nay. :-p – BFree

+25

SARG = Tìm kiếm đối số. Điều thú vị là: "SARG" trong tiếng Đức có nghĩa là "Quan tài", vì vậy tôi luôn phải mỉm cười khi mọi người nói về SARGABLE - có thể được đưa vào quan tài? :-) –

+0

sargability phụ thuộc vào môi trường của bạn. MySQL có tài liệu ở đây: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html –

Trả lời

178

Điều phổ biến nhất mà sẽ làm cho một truy vấn không sargable là bao gồm một lĩnh vực bên trong một chức năng trong mệnh đề where:

SELECT ... FROM ... 
WHERE Year(myDate) = 2008 

Các ưu SQL không thể sử dụng một chỉ mục trên myDate, ngay cả khi có. Nó theo nghĩa đen sẽ phải đánh giá chức năng này cho mỗi hàng của bảng. Tốt hơn để sử dụng:

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009' 

Một số ví dụ khác:

Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones' 
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL)) 

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford' 
Fixed: Select ... WHERE DealerName Like 'Ford%' 

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30 
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate()) 
+6

Sẽ bao gồm một hàm bên trong 'GROUP BY' làm cho truy vấn trở thành không thể sargable? –

+0

@MikeBantegui Chỉ cần bao gồm một trường trong một GROUP BY sẽ không nhất thiết phải làm cho nó không sargeable, không. Các chỉ mục phù hợp chắc chắn sẽ giúp truy vấn GROUP BY. – BradC

+1

* Một số công cụ cơ sở dữ liệu * (Oracle, PostgreSQL) hỗ trợ các chỉ mục trên biểu thức, không biết? – Craig

62

Đừng làm điều này:

WHERE Field LIKE '%blah%' 

Đó gây ra một bảng/index quét, vì giá trị NHƯ bắt đầu bằng một ký tự đại diện.

Đừng làm điều này:

WHERE FUNCTION(Field) = 'BLAH' 

Đó gây ra một bảng/index quét.

Máy chủ cơ sở dữ liệu sẽ phải đánh giá FUNCTION() đối với mọi hàng trong bảng và sau đó so sánh nó với 'BLAH'.

Nếu có thể, làm điều đó trong ngược lại:

WHERE Field = INVERSE_FUNCTION('BLAH') 

này sẽ chạy INVERSE_FUNCTION() chống lại các tham số một lần và vẫn sẽ cho phép sử dụng các chỉ số.

+3

Đề xuất của bạn với chức năng lật sẽ thực sự chỉ hoạt động khi dữ liệu vòng lặp của hàm (nghĩa là f (f (n)) = n). –

+4

Đúng. Tôi đã cân nhắc thêm INVERSE_FUNCTION nhưng không muốn gây nhầm lẫn. Tôi sẽ thay đổi nó. – beach

7

Trong câu trả lời này, tôi giả định cơ sở dữ liệu có đủ chỉ số bao gồm. Có đủ câu hỏi về this topic.

Rất nhiều lần khả năng thích ứng của truy vấn được xác định bởi điểm tới hạn của các chỉ mục có liên quan. Điểm bùng phát xác định sự khác biệt giữa tìm kiếm và quét chỉ mục trong khi tham gia một bảng hoặc kết quả được đặt thành một bảng khác. Một tìm kiếm là tất nhiên nhanh hơn nhiều so với quét toàn bộ một bảng, nhưng khi bạn phải tìm kiếm rất nhiều hàng, một quét có thể có ý nghĩa hơn. Vì vậy, trong số những thứ khác, một câu lệnh SQL là sargable hơn khi trình tối ưu hóa dự kiến ​​số hàng kết quả của một bảng sẽ nhỏ hơn điểm tới hạn của một chỉ mục có thể có trên bảng tiếp theo.

Bạn có thể tìm thấy bài đăng chi tiết và ví dụ here.

0

Để hoạt động được coi là sargable, không đủ để có thể sử dụng chỉ mục hiện tại.Trong ví dụ trên, thêm một cuộc gọi hàm vào một cột được lập chỉ mục trong mệnh đề where, sẽ vẫn có nhiều khả năng tận dụng lợi thế của chỉ mục đã định nghĩa. Nó sẽ "quét" aka lấy tất cả các giá trị từ cột đó (chỉ mục) và sau đó loại bỏ những giá trị không khớp với giá trị bộ lọc được cung cấp. Nó vẫn chưa đủ hiệu quả cho các bảng có số hàng cao. Điều gì thực sự xác định khả năng thích hợp là khả năng truy vấn để đi qua chỉ mục b-tree bằng cách sử dụng phương pháp tìm kiếm nhị phân dựa trên việc loại bỏ một nửa thiết lập cho mảng các mục đã sắp xếp. Trong SQL, nó sẽ được hiển thị trên kế hoạch thực hiện như là một "chỉ mục tìm kiếm".

Các vấn đề liên quan