Sử dụng IF trong T-SQL làm suy yếu hoặc phá vỡ bộ nhớ đệm kế hoạch thực hiện?


20

Tôi đã được đề xuất rằng việc sử dụng các câu lệnh IF trong các lô t-SQL là bất lợi cho hiệu suất. Tôi đang cố gắng tìm một số xác nhận hoặc xác nhận xác nhận này. Tôi đang sử dụng SQL Server 2005 và 2008.

Khẳng định là với lô sau: -

IF @parameter = 0
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

SQL Server không thể sử dụng lại kế hoạch thực hiện được tạo bởi vì lần thực hiện tiếp theo có thể cần một nhánh khác. Điều này ngụ ý rằng SQL Server sẽ loại bỏ hoàn toàn một nhánh khỏi kế hoạch thực hiện trên cơ sở thực hiện hiện tại, nó có thể xác định nhánh nào là cần thiết. Điều này có thực sự đúng không?

Ngoài ra những gì xảy ra trong trường hợp này: -

IF EXISTS (SELECT ....)
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

Trường hợp không thể xác định trước chi nhánh nào sẽ được thực hiện?



1
SQL Server có thể và không sử dụng lại kế hoạch thực hiện vì nó không xem xét các nhánh, chỉ các câu lệnh có trong các nhánh.
MartinC

Câu trả lời:


10

SQL Server tối ưu hóa quá trình biên dịch kế hoạch truy vấn cho thủ tục được lưu trữ bằng cách bỏ qua các nhánh có điều kiện bên trong thủ tục được lưu trữ. Kế hoạch sẽ được tạo dựa trên các tham số được sử dụng cho lần thực hiện đầu tiên, điều này sẽ gây ra vấn đề nếu các tham số khác nhau cho các nhánh.

Tôi sẽ đặt SQL cho mỗi nhánh vào thủ tục được lưu trữ của riêng chúng, để kế hoạch được tạo ra dựa trên việc sử dụng thực tế các tham số cho nhánh đó.


6

Phím tắt duy nhất sẽ là IF 1 = 1

Cả @parameter và EXISTS vẫn yêu cầu xử lý cho "trường hợp chung" ( @parameter = 42giả sử)

Nói rằng ... kế hoạch thực hiện thực tế nói gì cũng như trình hồ sơ nắm bắt các sự kiện tái diễn? (Tôi không thích các kế hoạch ước tính theo câu trả lời của Jao)


3

Cố gắng hiển thị kế hoạch thực hiện ước tính, không thực tế. Bạn sẽ thấy cái đầu tiên chứa CONDtoán tử.

Toán tử này cũng được bao gồm trong kế hoạch thực hiện lưu trữ. Trong ví dụ của bạn, kế hoạch loại bỏ ước tính sẽ chứa một toán tử COND và 2 nhánh CHỌN và do đó sẽ hoàn toàn có thể tái sử dụng. Bởi vì khi thực thi một lô SQL Server sẽ đánh giá không chỉ các câu lệnh DML mà còn cả các câu lệnh khác, lấy chúng từ kế hoạch.

Kế hoạch thực hiện bên trong là một cấu trúc tương tự như cây biểu thức.


0

Các kế hoạch sẽ được tạo dựa trên các tham số được truyền vì vậy trong thực tế tôi nói Không - có logic điều kiện thường dựa trên các tham số không gây bất lợi cho hiệu suất.

Bạn sẽ nhận được nhiều gói được tạo ra, giả sử các tham số gây ra đủ phương sai để trình tối ưu hóa truy vấn nhận thấy.

Bạn có thể thấy cái nào bằng cách chuyển đổi trên gói Hiển thị thực thi, chạy các tập lệnh - chú ý sự khác biệt trong kế hoạch. Khi bạn chạy các thủ tục (tôi giả sử các thủ tục được lưu trữ ở đây), bạn sẽ thấy lần đầu tiên thường nhanh hơn, lần truy cập thứ hai sử dụng gói được lưu trữ. Thay đổi tham số và lặp lại sau đó chạy các tham số ban đầu - về lý thuyết, kế hoạch sẽ vẫn ở trong bộ đệm nhưng nó phụ thuộc vào việc sử dụng máy chủ (đánh dấu vào bộ đệm - chúng không tồn tại mãi mãi ..), v.v.


0

Có thể nó đã được cải thiện vào năm 2005 và 2008, nhưng sử dụng điều kiện vào năm 2000 có thể sẽ tệ hơn bạn mô tả, nó sẽ biên soạn một kế hoạch để xử lý tốt nhất lần chạy đầu tiên của thủ tục và sau đó sử dụng kế hoạch đó để thực hiện thủ tục ngay cả khi có điều kiện đã thay đổi Theo kinh nghiệm của tôi, điều này gây ra các truy vấn chạy trong vài phút để chạy trong vài giờ. Mặc dù bây giờ tôi sử dụng 2008 và đã sử dụng năm 2005 nhưng tôi không thể nhận xét về cách thức hoạt động của các loại tiền mã hóa ở đó vì tôi không còn sử dụng chúng nữa.


2
2005+ có biên dịch lại mức độ câu lệnh để bạn không có "một kế hoạch cho mỗi sp" mọi lúc
gbn
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.