Truy vấn có thể nói


7

Tôi hy vọng câu hỏi rất đơn giản, tôi hiện đang có một số tập lệnh mà tôi đã kế thừa trong dự án của mình được quản trị viên cơ sở dữ liệu xem xét. Điều này chưa bao giờ được thực hiện trước khi rõ ràng và rất nhiều vấn đề đang được tìm thấy.

Tôi hơi mới với điều này, nhưng sự hiểu biết của tôi về SQL Sargable và Non-Sargable là hàm vi phạm đang hoạt động trên cột và do đó cản trở chỉ mục (giả sử có một cái) dẫn đến việc quét cột và một hiệu suất đạt. Mã này có một số chức năng trong đầu vào, rất nhiều thứ nhỏ, như

Where a.date between 'inputdate' and dateadd(day,1,'inputdate')

DBA đã đưa ra lập trường rằng bất kỳ truy vấn nào có chứa một hàm trong WHEREmệnh đề là không thể saragable. Tôi sẽ bỏ qua vấn đề với anh ta vì tranh cãi sẽ chẳng đưa tôi đến đâu ngoại trừ một quản trị viên bực mình và quyền truy cập của tôi bị hạn chế.

Nhưng vì lợi ích của kiến ​​thức, có trường hợp anh ta đúng và bất kỳ chức năng nào trong WHEREmệnh đề là một vấn đề, bất kể chức năng hoặc vị trí?


4
Không, nếu truy vấn là những gì bạn thể hiện, anh ấy hoàn toàn sai. Nó là khá lớn như nó là. (Tôi sẽ không sử dụng BETWEENvới ngày nhưng đó là một vấn đề khác, không liên quan) Bạn chỉ hiển thị cho chúng tôi một truy vấn. Nếu bạn có hàng chục truy vấn với các điều kiện không thể thực hiện được và các lệnh gọi hàm, chúng có thể đã bỏ lỡ một truy vấn thực sự có thể thực hiện được.
ypercubeᵀᴹ

1
Đó có thể là trường hợp, rằng tôi đã bỏ lỡ một cái gì đó trong số các mã. Nhưng tôi đã thúc đẩy để làm rõ về vấn đề os Sargability đặc biệt vì lợi ích của riêng tôi và được cho biết rằng nó quan trọng đối với bất kỳ chức năng nào trong mệnh đề WHERE hoặc ON. Điều đó không hợp lý với tôi vì lý do cho vấn đề ở nơi đầu tiên là cho phép các chỉ mục được sử dụng ... và bạn không thể lập chỉ mục một đầu vào.
sten

1
Không phải SQL Server có các chỉ mục chức năng, hoặc ít nhất, các cột được tính toán với các chỉ mục?
Vérace

2
BTW, thuật ngữ "sargable" thường liên quan đến các vị từ riêng lẻ, không liên quan đến các truy vấn.
mustaccio

1
@BrentOzar có một khả năng dễ hiểu về tính dễ hiểu tại brentozar.com/archive/2010/06/sargable-why-opes-is-slow
Max Vernon

Câu trả lời:


7

Như ypercube đã nhận xét

Không, nếu truy vấn là những gì bạn thể hiện, anh ấy hoàn toàn sai. Nó là khá lớn như nó là.

Bạn có thể xác minh điều này bằng cách:

  • Tạo bảng thử nghiệm đơn giản với cột [Ngày].
  • Chèn một số lượng lớn các hàng với ngày khác nhau.
  • LƯU Ý: Trong "số lượng lớn" và "ngày thay đổi" ở trên là một biện pháp phòng ngừa để đảm bảo rằng truy vấn của bạn đủ chọn lọc . Nếu không, trình tối ưu hóa có thể chọn không sử dụng chỉ mục của bạn trong mọi trường hợp.
  • Tạo kế hoạch truy vấn cho truy vấn của bạn (một lần với chỉ mục trên cột Ngày và một lần không có).
  • Bạn cũng có thể sử dụng IO STATISTICS để thể hiện sự khác biệt.
  • Nếu bạn có đủ dữ liệu thử nghiệm, sự khác biệt sẽ dễ dàng quan sát được.

Khi bạn đã có bằng chứng, tôi khuyên bạn nên đưa nó lên với DBA. Tuy nhiên, đừng tranh cãi. Chỉ cần hiển thị kiểm tra và dữ liệu chứng minh chỉ số được sử dụng.

Vấn đề là bạn không muốn bị buộc phải cúi người về phía sau để tránh những vấn đề không tồn tại.

May mắn thay trong trường hợp bạn chứng minh, sẽ không có vấn đề gì khi di chuyển các chức năng bên ngoài truy vấn. Ví dụ

DECLARE @FromDate date ='inputdate',
        @ToDate date = DATEADD(day, 1, @FromDate)

Trong thực tế, những điều trên thậm chí có thể được duy trì nhiều hơn trong thời gian dài.

Tuy nhiên, sẽ đến lúc bạn có thứ gì đó không thể thay đổi một cách tầm thường theo mong muốn của DBA. Nhu la:

--Granted this probably belongs in a JOIN clause, but is primarily for illustrative purposes.
--Also the issue of sargability applies just as much to JOIN clauses as WHERE clauses
WHERE a.date >= b.date
  AND a.date < DATEADD(day, 1, b.date)

Cách duy nhất để đưa hàm này ra khỏi mệnh đề WHERE là tính toán trước một cột khác b.NextDay. Đó chính xác là lý do tại sao bạn cần DBA để hiểu chính xác Sargability. Tức là ở trên:

  • Sẽ có thể tận dụng một chỉ số trên a.date.
  • Nhưng không thể tận dụng một chỉ số trên b.date.
  • Vì vậy, cột / chỉ mục được chọn nhiều nhất không nên có chức năng được áp dụng, nhưng cái khác có thể.
  • Cố gắng hack một giải pháp mà không có chức năng trong mệnh đề WHERE sẽ làm giảm cả khả năng bảo trì và hiệu suất.

Nếu bạn thực sự không thể mua được từ DBA, có lẽ những điều sau đây sẽ hoạt động và bỏ qua các quy tắc tôn sùng hàng hóa của họ:

;WITH CTE_B AS (
    SELECT  b.Date, DATEADD(day, 1, b.DATE) AS NextDay
    FROM    b
    )
SELECT  ...
WHERE   a.Date >= CTE_B.Date
    AND a.Date < CTE_B.NextDay

Trình tối ưu hóa gần như chắc chắn sẽ tối ưu hóa điều này theo cách tương tự như khi hàm nằm trong WHEREmệnh đề, vì vậy bạn không nên gõ hiệu suất. Nhưng đó chắc chắn là một sự giảm bớt không cần thiết trong khả năng bảo trì.


Điều này nghe có vẻ tồi tệ, nhưng tôi đang sống trong thời kỳ đồ đá. CTE sẽ không hoạt động. WITHsẽ không đi làm ... ít nhất là không phải bây giờ. Tất cả các truy vấn được chạy qua một hệ thống báo cáo có các câu lệnh đóng hộp. Những cái tương tự tôi đã thừa hưởng. Kế hoạch cuối cùng của tôi là chuyển tất cả sang các tập lệnh thực hiện công việc tự động hiện đang chạy thủ công. Có, các DBA có thể sử dụng CTE và thực tế họ đã đề xuất một kế hoạch như của bạn. Và tôi không muốn tham gia một cuộc thi bực mình với họ vì họ có thể làm cho cuộc sống khó khăn.
sten

Tôi cũng không muốn mất thiện chí mà tôi có được khi trở thành người đầu tiên trong số các Phân tích thực sự đến gặp họ và hỏi họ nghĩ gì trước khi chạy mã chống lại máy chủ sản xuất. Chính trị.
sten
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.