2012-01-19 33 views
5

Tôi có yêu cầu tìm kiếm một số bảng khác nhau trong cơ sở dữ liệu SQL Server của mình. Và tôi cần phải sắp xếp các kết quả dựa trên bảng mà trận đấu xảy ra.Tối ưu hóa tìm kiếm toàn văn bản trên nhiều bảng

Cách tiếp cận tôi đã thực hiện được hiển thị bên dưới. Tuy nhiên, điều này dường như không hiệu quả lắm khi lượng dữ liệu tăng lên.

Có ai có thể đề xuất bất kỳ thủ thuật nào để tối ưu hóa điều này không?

-- Full-text query 
DECLARE @FtsQuery nvarchar(100) 
SET @FtsQuery = 'FORMSOF(INFLECTIONAL, detail)' 

-- Maximum characters in description column 
DECLARE @MaxDescription int 
SET @MaxDescription = 250 

SELECT 1 AS RankGroup, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) AS Description FROM Table1 
    INNER JOIN CONTAINSTABLE(Table1, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table1.Id 
UNION SELECT 2, FTS.Rank, Id, Title, NULL FROM Table2 
    INNER JOIN CONTAINSTABLE(Table2, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table2.Id 
UNION SELECT 3, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table3 
    INNER JOIN CONTAINSTABLE(Table3, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table3.Id 
UNION SELECT 4, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table4 
    INNER JOIN CONTAINSTABLE(Table4, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table4.Id 
UNION SELECT 5, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table5 
    INNER JOIN CONTAINSTABLE(Table5, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table5.Id 
ORDER BY RankGroup, Rank DESC 

Một ý tưởng tôi muốn xem là tạo chế độ xem được lập chỉ mục và sau đó thực hiện tìm kiếm trên chế độ xem. Nhưng kể từ khi xem sẽ cần những UNION s, thật khó để xem nó sẽ hiệu quả hơn thế nào.

+0

Một tối ưu hóa đơn giản mà bạn có thể thực hiện một cách an toàn là thay thế 'UNION' bằng 'UNION ALL'. Để biết thêm thông tin: http://stackoverflow.com/questions/49925/what-is-the-difference-between-union-and-union-all – niaher

Trả lời

7

Đây là một vấn đề khó khăn, vì CONTAINSTABLE chỉ có thể tìm kiếm chỉ mục FTS của một bảng tại một thời điểm. Giải pháp UNION của bạn ở trên là tốt miễn là hiệu suất của bạn được chấp nhận.

Chúng tôi phải đối mặt với cùng một vấn đề cần phải tìm kiếm hiệu quả nhiều cột từ nhiều bảng trong một truy vấn. Những gì chúng tôi đã làm là tổng hợp tất cả dữ liệu từ các cột và bảng này thành một bảng chỉ đọc. truy vấn của chúng tôi sau đó chỉ cần một cuộc gọi duy nhất CONTAINSTABLE

CONTAINSTABLE(AggregatedTable, AggregatedColumn, @FtsQuery) 

Chúng tôi có một công việc theo lịch trình chạy mỗi 5-10 phút và từng bước tập hợp bất kỳ nội dung sửa đổi từ bảng nguồn của chúng tôi vào đơn chỉ đọc bảng nội dung tổng hợp của chúng tôi.

Nói chung có vẻ như sử dụng FTS trong bất kỳ cơ sở dữ liệu có kích thước hợp lý và tải người dùng có nghĩa là bạn luôn chiến đấu với hiệu suất. Nếu bạn thấy rằng bất kể bạn làm gì, bạn không thể nhận được hiệu suất có thể chấp nhận được, bạn có thể cần điều tra các công nghệ khác như Lucene.

+0

Thú vị. Bạn đã thực hiện loại phương pháp nào để lấy dữ liệu đã thay đổi và đẩy nó vào bảng tổng hợp? Và công việc theo lịch trình thường mất bao lâu để chạy? – mg1075

+1

Chúng tôi sử dụng một proc được lưu trữ được lên lịch bởi tác nhân sql để cập nhật bảng không chuẩn hóa. Dữ liệu cơ sở của chúng tôi có một dấu ngày giờ trên mỗi hàng cho biết khi hàng được chạm lần cuối (được chèn hoặc cập nhật) để chúng tôi sử dụng nó để chỉ tăng số lượng mỗi 5 hoặc 10 phút. Tải ban đầu của chúng tôi mất một giờ hoặc lâu hơn, nhưng số lượng gia tăng chỉ mất 10 hoặc 20 giây. –

+0

Cảm ơn bạn đã nhập. Tôi cho rằng vấn đề duy nhất cần quan tâm là: (1) thời gian để truy vấn các bảng để xác định hồ sơ đủ điều kiện cho bản cập nhật và (2) nếu có thời gian ngừng hoạt động và bản cập nhật thường chạy - và nhìn tại một hồ sơ chỉ cho đến nay trở lại trong thời gian - không chạy được. – mg1075

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