2011-10-24 29 views
5

Tôi đang cố chạy truy vấn từ ADO.NET bằng SQL Server 2008R2. Tôi đang sử dụng CTE để cung cấp phân trang và thêm thông số cho @Offset@Limit, cả hai số nguyên.Thời gian chờ ADO.NET nhưng hoạt động tốt trong SSMS

Tôi đang tạo một truy vấn tham số tùy thuộc vào đầu vào của người dùng. Kết quả cuối cùng là:

;WITH Results_CTE AS (
    SELECT ld.* , ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE 
    WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
OPTION (RECOMPILE) 

Tôi đang sử dụng một số mệnh đề giống như lý do tại sao tôi có OPTION RECOMPILE. Nếu tôi khai báo thông số qua SSMS và chạy như vậy:

declare @postcode varchar(10) = 'SW1 1AA'; 
declare @Offset int = 0; 
declare @Limit int = 10; 

Tôi nhận được thời gian phản hồi rất nhanh (dưới 1s). Nếu tôi thử điều này với ADO.NET, tuy nhiên, nó mất mãi mãi. Tôi đã cố gắng thêm các thông số với cả hai:

cmd.Parameters.AddWithValue("@Offset", startRowIndex) // times out 
cmd.Parameters.AddWithValue("@Limit", limit) 

cmd.Parameters.Add(New SqlParameter("@Offset", SqlDbType.BigInt)) // also times out 
cmd.Parameters.Item("@Offset").Value = startRowIndex 
cmd.Parameters.Add(New SqlParameter("@Limit", SqlDbType.BigInt)) 
cmd.Parameters.Item("@Limit").Value = limit 

Nếu chỉ có một vài dòng trả về bởi truy vấn đầu tiên và mặc dù tôi thả @Offset@Limit lọc, tôi nhận được một thời gian phản hồi tốt. Có cách nào tôi có thể tăng tốc độ này lên sử dụng phân trang không?

EDIT: Tôi đang đi qua trong tham số @postcode (mà là một chuỗi trong .NET qua này:

cmd.Parameters.AddWithValue("@Postcode", normalizedPostcode) 
+0

@close cử tri. Đây không phải là một trò lừa bịp. Câu hỏi trước là về giải thích hành vi khác nhau với các biến không phải tham số. Cả hai được xử lý khác nhau bởi SQL Server. –

+0

Bạn có thể hiển thị mã mà bạn chuyển vào tham số '@ postcode' không? –

+0

Đây có phải là thời điểm SQL không? Không có khả năng rằng thời gian của nó ra cố gắng để có được một kết nối (ví dụ như bởi vì bạn có vô số các kết nối mở vẫn còn khi bạn làm điều này) hoặc bất cứ điều gì khác như thế? – Chris

Trả lời

7

mã ADO.NET của bạn là đi qua trong một tham số của a different datatype so với cái bạn đang thử nghiệm trong SSMS và bạn đang nhận được vấn đề diễn viên tiềm ẩn.

không sử dụng

cmd.Parameters.AddWithValue("@postcode", normalizedPostcode) 

vì điều này sẽ tự động tạo ra mộtTham sốvà bạn sẽ nhận được các phôi ẩn trong kế hoạch thực thi của bạn có nghĩa là không thể sử dụng một chỉ mục. Thay vào đó, thay vào đó, hãy chuyển vào một thông số được tạo rõ ràng là varchar.

cmd.Parameters.Add("@postcode", SqlDbType.Varchar, 10) 
+0

Mẹo tuyệt vời. Điều chỉnh chính xác các tham số trong .NET thành DBType nhận được nhiều phản hồi tức thì. – Echilon

2

1) Đối với thông số @postcode please specify the length.

cmd.Parameters.Add("@postcode", SqlDbType.VarChar, 10).Value = str

2) Viết lại các truy vấn:

;WITH Results_CTE AS (
    SELECT ld.Key_Field, ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE a 
INNER JOIN list..List_Data b ON a.Key_Field = Key_Field 
WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
--OPTION (RECOMPILE) 

Note 1: Tôi cho rằng Key_Field là khóa chính (cụm) cho List_Data bảng.

Lưu ý 2: Kiểm tra xem bạn có chỉ mục trên các trường VALUE_2010 và Mã bưu điện không. Nếu bạn có SQL 2008+ thì bạn có thể tạo chỉ mục đã lọc:

--UNIQUE if Postcode has unique values for VALUE_2010 IS NOT NULL 
CREATE [UNIQUE] INDEX aaa 
ON MySchema.List_Data (Postcode) 
WHERE VALUE_2010 IS NOT NULL 
+0

Điều này dường như cải thiện tốc độ một vài phần nghìn giây, nhưng nó thay đổi. Không thể đau vì biện pháp tốt. – Echilon

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