2008-11-24 25 views
15

Tôi có một truy vấn sql chạy siêu nhanh, khoảng một giây, khi không sử dụng các biến, như:Tại sao SQL Server chạy chậm khi sử dụng các biến?

WHERE id BETWEEN 5461094 and 5461097 

Nhưng khi tôi có:

declare @firstId int 
declare @lastId int 

set @firstId = 5461094 
set @lastId = 5461097 

... 
    WHERE id BETWEEN @firstId and @lastId 

... truy vấn chạy rất chậm , chỉ hoàn thành sau vài phút. Tại sao nó lại xảy ra? Tôi cần sử dụng các biến. Tôi có thể thực hiện bất kỳ cải tiến nào để tránh các vấn đề về hiệu năng này không?

Trả lời

10

Đó là vì khi các giá trị được mã hóa cứng, nó có thể tra cứu the statistics nó có trên dữ liệu trong bảng và tìm ra truy vấn tốt nhất để chạy. Hãy xem các kế hoạch thực hiện của từng truy vấn này. Nó phải được quét khi sử dụng các biến của bạn.

nếu phạm vi luôn nhỏ, bạn có thể sử dụng gợi ý chỉ mục để trợ giúp điều này.

+0

Trong Oracle, nếu phạm vi luôn nhỏ, mọi thứ sẽ ổn. Nó sẽ chọn kế hoạch dựa trên các biến đầu tiên. Nếu nó luôn nhỏ, bạn luôn ổn. Đó là trường hợp xoay giữa các thái cực. Tôi nghĩ rằng SS thêm một cái gì đó giống như nhìn trộm gần đây ... có thể '05 hoặc '08. –

0

ID có trong chỉ mục (ví dụ: Khóa chính) không? Nếu không, hãy thử thêm một.

Một điều khác có thể là trong trường hợp đầu tiên (nhanh) truy vấn được thực hiện hơi khác một chút. Điều phổ biến nhất mà tôi đã thấy xảy ra là các phép nối được thực hiện theo một thứ tự không hiệu quả. Thử đặt lại các kết nối hoặc chuyển đổi một số thành truy vấn phụ. Nếu bạn đăng thêm truy vấn của mình, chúng tôi có thể hỗ trợ thêm.

3

vui là mã này sẽ được nhanh chóng quá:

DECLARE @sql VARCHAR(8000) 

SET @sql = 'SELECT * FROM table_x WHERE id BETWEEN ' + CAST(@firstId AS VARCHAR) + ' AND ' + CAST(@lastId AS VARCHAR) 

EXEC (@sql) 

(MSSQL 2000)

19

OK,

  1. Bạn đang Optimizer và Kế hoạch truy vấn là một phương tiện.
  2. Tôi sẽ cung cấp cho bạn một truy vấn và bạn phải chọn phương tiện.
  3. Tất cả những cuốn sách trong thư viện có một số tuần tự

truy vấn của tôi là Đi đến thư viện và làm cho tôi tất cả những cuốn sách từ 3 đến 5

Bạn muốn chọn một quyền xe đạp, nhanh chóng, giá rẻ, hiệu quả và đủ lớn để mang lại 3 cuốn sách.

Truy vấn mới.

Chuyển đến thư viện và tải tất cả sách từ @x đến @y.

Chọn xe.

Hãy tiếp tục.

Đó là những gì sẽ xảy ra. Bạn có chọn một xe tải trong trường hợp tôi yêu cầu sách giữa 1 và Maxvalue không? Đó là quá mức cần thiết nếu x = 3 và y = 5. SQL phải chọn kế hoạch trước khi nó nhìn thấy các con số.

+0

cập nhật các thủ tục được lưu trữ và thêm 'tùy chọn biên dịch lại 'vào cuối – atoms

+0

Đó là một lời giải thích tuyệt vời về những gì Microsoft đang làm sai. Thực tế cuộc sống: hỏi giá trị biến, sau đó, chọn chiếc xe thích hợp. – norgematos

1

Có vẻ như truy vấn này liên quan đến một thủ tục được lưu trữ, kế hoạch thực hiện của nó sẽ được biên dịch lần đầu tiên khi proc được thực hiện và sau đó được sử dụng lại cho các lần thực hiện tiếp theo.

Có thể là kế hoạch được biên soạn thực sự tồi tệ đối với các trường hợp mà firstid thực sự gần với thời gian chờ, tuy nhiên nó thực sự tốt khi các giá trị ở xa nhau.

Thử bật tùy chọn WITH RECOMPILE trên proc đã lưu trữ của bạn. Nếu nó giải quyết vấn đề và bạn hài lòng với proc được biên dịch lại mỗi khi nó được thực hiện (bạn sẽ nhận được một hit hiệu suất) để nó ở đó. Nếu bạn vẫn không hài lòng với việc thực hiện xem xét lại việc kiến ​​trúc lại proc để nó không cần biên dịch lại.

0

Trên thực tế, người ta đã trả lời rất tốt, tôi chỉ viết ở đây một cách giải quyết vì nó làm việc cho tôi:

Tạo một thủ tục lưu trữ với SQL

WHERE id BETWEEN @firstId and @lastId 

Sau đó gọi proc lưu trữ với các tham số @firstId và @lastId và nó sẽ tăng tốc. Tôi vẫn không 100% lý do tại sao nó hoạt động, nhưng nó hoạt động.

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