10

Tôi có một truy vấn đơn giản dựa trên hai bảng toàn văn được lập chỉ mục, nhưng nó chạy rất chậm khi tôi có CHỨA kết hợp với bất kỳ thêm HOẶC tìm kiếm. Như đã thấy trong kế hoạch thực hiện, hai tìm kiếm toàn văn đều đè bẹp hiệu suất. Nếu tôi truy vấn chỉ với 1 CONTAINS, hoặc không, truy vấn là phụ thứ hai, nhưng thời điểm bạn thêm HOẶC vào kết hợp truy vấn sẽ bị lỗi.Thêm nhiều HOẶC tìm kiếm với CHỨA mang Query để Bò

Hai bảng không có gì đặc biệt, chúng không quá rộng (42 cols trong một, 21 ở mặt kia; có thể 10 cols là FT được lập chỉ mục trong mỗi) hoặc thậm chí chứa nhiều bản ghi (36k recs in the big of cả hai).

tôi đã có thể giải quyết hiệu quả hoạt động thông qua việc tách hai CHỨA tìm kiếm thành họ riêng CHỌN truy vấn và sau đó UNION ba với nhau. UNION này có giải pháp cho hy vọng duy nhất của tôi không?

Cảm ơn.

SELECT  a.CollectionID 
FROM  collections a 
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
WHERE  a.CollrTeam_Text LIKE '%fa%' 
      OR CONTAINS(a.*, '"*fa*"') 
      OR CONTAINS(b.*, '"*fa*"') 

Kế hoạch thực hiện (đoán tôi cần thêm danh tiếng trước khi tôi có thể gửi hình ảnh): http://yfrog.com/7dslowcontainsj http://desmond.yfrog.com/Himg265/scaled.php?tn=0&server=265&filename=slowcontains.jpg&xsize=640&ysize=640

+1

Tôi nên chỉ ra @ChiragRoy cho biết đây là vấn đề đã biết với SQL2008/R2 với trường hợp PSS mở. Nhưng tôi tò mò nếu có ai khác đã gặp phải vấn đề và tìm ra giải pháp thay thế hoặc lý do cho vấn đề này. – scolja

+1

Tôi không hoàn toàn chắc chắn giao thức là gì để đánh dấu một câu trả lời duy nhất như đã trả lời. Trong trường hợp này, UNION chắc chắn giải quyết vấn đề, nhưng nó sẽ xuất hiện tôi có thể giải quyết vấn đề và nhận được hiệu suất tốt hơn với CONTAINSTABLE. Tôi thực sự đánh giá cao phản hồi của mọi người về câu hỏi. – scolja

Trả lời

6

Tôi rất tò mò muốn xem liệu LEFT JOIN với một CONTAINSTABLE tương đương có thể thực hiện tốt hơn không. Một cái gì đó như:

SELECT  a.CollectionID 
FROM  collections a 
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
LEFT JOIN CONTAINSTABLE(a, *, '"*fa*"') ct1 on a.CollectionID = ct1.[Key] 
LEFT JOIN CONTAINSTABLE(b, *, '"*fa*"') ct2 on b.CollectionID = ct2.[Key] 
WHERE  a.CollrTeam_Text LIKE '%fa%' 
      OR ct1.[Key] IS NOT NULL 
      OR ct2.[Key] IS NOT NULL 
+2

Đáng kinh ngạc, hiệu suất tốt hơn. Một lần nữa DISTINCT đã được thêm vào và CONTAINSTABLE cần các tên bảng thực tế, nhưng với một số chỉnh nhỏ nó chạy hoàn hảo. So sánh chi phí giữa 3 phương pháp: 29%, 32% và 38% (CONTAINSTABLE, LEFT OUTER JOIN, sau đó UNION). Hợp lý đọc bây giờ 1/5 của truy vấn UNION. Làm tốt. – scolja

+0

nếu bạn chỉ cần 'CollectionID' thì bạn thậm chí không cần thực hiện các phép nối. Bạn có thể sử dụng 'ct1.Key làm CollectionID' –

2

tôi sẽ gợi ý cho UNION mỗi khi truy vấn riêng của họ, nhưng khi tôi đọc câu hỏi của bạn tôi thấy rằng bạn đã tìm thấy điều đó. Tôi không thể nghĩ ra một cách tốt hơn, vì vậy nếu nó giúp sử dụng nó. Phương thức UNION là một cách tiếp cận phổ biến đối với truy vấn hoạt động kém có một số điều kiện OR trong đó mỗi điều kiện hoạt động tốt.

+0

+1 Tôi cũng sẽ đề xuất UNION. Như một lưu ý, tôi sẽ nói rằng UNION là giải pháp * đúng * chứ không phải giải pháp thay thế. –

+0

Cảm ơn, sự đảm bảo rằng cách tiếp cận UNION rất hữu ích; cộng với nó không làm tổn thương rằng truy vấn chạy tốt ngay bây giờ để khởi động. – scolja

+1

Và nếu hai báo cáo công đoàn sẽ loại trừ lẫn nhau mỗi lần, sau đó sử dụng UNION ALL để thực hiện các hiệu suất bổ sung. – HLGEM

1

Tôi có thể sẽ sử dụng UNION. Nếu bạn thực sự chống lại nó, bạn có thể thử một cái gì đó như:

SELECT a.CollectionID 
FROM collections a 
    LEFT OUTER JOIN (SELECT CollectionID FROM collections WHERE CONTAINS(*, '"*fa*"')) c 
    ON c.CollectionID = a.CollectionID 
    LEFT OUTER JOIN (SELECT CollectionID FROM determinations WHERE CONTAINS(*, '"*fa*"')) d 
    ON d.CollectionID = a.CollectionID 
WHERE a.CollrTeam_Text LIKE '%fa%' 
    OR c.CollectionID IS NOT NULL 
    OR d.CollectionID IS NOT NULL 
+0

Tôi đã phải thêm DISTINCT, nhưng điều này thực sự dẫn đến cải thiện hiệu suất nhỏ so với phương pháp UNION.So sánh chi phí là 46% đến 54% với khoảng 2/3 số lần đọc hợp lý. Hấp dẫn! – scolja

0

Chúng tôi đã trải nghiệm các vấn đề chính xác cùng và vào thời điểm đó, đặt nó xuống để truy vấn của chúng tôi được hình thành nặng - đó SQL 2005 đã để chúng tôi có được đi với nó, nhưng năm 2008 sẽ không được.

Cuối cùng, chúng tôi chia truy vấn thành 2 SELECT được gọi bằng cách sử dụng IF. Vui mừng người khác đã có cùng một vấn đề và đó là một vấn đề đã biết. Chúng tôi đã nhìn thấy các truy vấn trên một bảng có ~ 150.000 hàng + toàn văn từ < 1 giây (2005) đến 30 giây (2008).

+1

Chính xác! Truy vấn này ban đầu làm việc tốt trên một máy SQL 2000, nhưng một khi chúng tôi chuyển sang SQL 2008 này xuất hiện. Chào mừng bạn đến với câu lạc bộ mới của chúng tôi. – scolja

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