2011-09-07 31 views
5

Xem xét việc này khác biệt hiệu suất SQL, nơi trong lần đầu tiên, tôi chọn tất cả 26.000 hàng, và trong lần thứ hai, tôi chỉ muốn là người đầu tiên 5.hiệu suất lớn nhúng với TOP trong SQL Server

SELECT tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.[timestamp] 

vs

SELECT TOP (5) tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.[timestamp] 

Without: CPU = 201 | Reads: 6880 | Writes: 0 | Duration: 451 
With: CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188 

Điều này không có ý nghĩa với tôi ... Có cách nào khác để giải quyết vấn đề này không?

Sau khi Martin đề xuất một THỐNG KÊ THỰC HIỆN trên tất cả các bảng có liên quan, có một cải tiến nhỏ, nhưng mẹo thay đổi số tiền TOP thành một tham số hoạt động tốt nhất.

Trước khi thống kê xây dựng lại:

CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188 

Sau khi thống kê xây dựng lại:

CPU = 127734 | Reads: 4100436 | Writes: 2656 | Duration: 16880 

Với tham số:

CPU = 218 | Reads: 6899 | Writes: 0 | Duration: 83 

Query với tham số:

DECLARE @TOP INT; SET @TOP=5; 
SELECT TOP (@TOP) tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.timestamp desc 

Một nhận xét cuối cùng cho những người bạn sử dụng Khung thực thể; nếu bạn có kinh nghiệm hành vi này, bạn có thể mô phỏng các hành vi tương tự thông số dựa trên như sau:

.Take(100).ToList().Take(5) 

Tôi biết nó không phải là đẹp, nhưng đó là cách duy nhất để kích hoạt các kế hoạch thực hiện chính xác nếu bạn đang sử dụng khuôn khổ thực thể theo như tôi có thể nói.

Cảm ơn bạn đã chỉ cho tôi đúng hướng Martin!

+0

Bạn sẽ nhận được kế hoạch thực hiện truy vấn hoạt động kém (tốt nhất là 2 để so sánh trước/sau). – Justin

+3

Thú vị. Vui lòng đăng kế hoạch. Tôi đoán 'TOP 5' có thể có một số vòng lặp lồng nhau, nơi vòng kia không? Ngoài ra, nếu bạn thử 'DECLARE @TOP INT; SET @ TOP = 5; CHỌN TOP (@TOP) ... ' –

+0

Hãy đăng bài đó làm martin câu trả lời :) Nó phải làm một chuyển đổi tiềm ẩn ở đâu đó ... điều đó thật điên rồ. CẢM ƠN! – NKCSS

Trả lời

3

Sau khi thảo luận trong các nhận xét, có vẻ như vì một số lý do mà SQL Server đang chọn để tối ưu hóa cho trường hợp "Chỉ 5 hàng đầu tiên" là phụ tối ưu. Nó có thể sẽ sử dụng các toán tử không chặn như các vòng lồng nhau tham gia thay vì chặn các vòng lặp như tham gia băm. Khi bạn không thể đăng các kế hoạch thực hiện, rất khó để biết chính xác lý do tại sao nhưng so sánh các kế hoạch cho cả hai phiên bản của truy vấn và xem xét thực tế so với số hàng ước tính trong kế hoạch thực hiện thực tế cho truy vấn vấn đề nên đặt một số ánh sáng về vấn đề này.

Dường như trong trường hợp này việc ẩn thông tin TOP 5 từ trình tối ưu hóa tại thời gian biên dịch là đủ để cung cấp cho bạn gói mà bạn muốn;

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