2013-08-15 18 views
7

Tôi đã có một chức năng tìm kiếm các bài báo mà trông như thế này (chứa hơn 5 mục tìm kiếm):T-SQL - Làm cách nào để tôi có thể thực hiện truy vấn SELECT với nhiều mệnh đề LIKE nhanh hơn?

SELECT TOP 5 * 
FROM NewsArticles 
WHERE (headline LIKE '% sustainable %'OR 
headline LIKE '% sustainability %' OR 
headline LIKE '% conservation %' OR 
headline LIKE '% environmental % OR 
headline LIKE '% environmentally %') 
OR 
(body LIKE '% sustainable %'OR 
body LIKE '% sustainability %' OR 
body LIKE '% conservation %' OR 
body LIKE '% environmental % OR 
body LIKE '% environmentally %') 
ORDER BY publishDate DESC 

Truy vấn này được thiết kế để kéo ra 5 câu chuyện tin tức hàng đầu liên quan đến phát triển bền vững và ngồi trên trang chủ về tính bền vững chính của tôi. Tuy nhiên, phải mất một lúc để chạy và trang tải chậm. Vì vậy, tôi đang tìm cách để tăng tốc độ này. Có rất nhiều điều khoản NHƯ dường như cồng kềnh vì vậy tôi đã thử một cái gì đó với lệnh JOIN như thế này:

CREATE TABLE #SearchItem (Search varchar(255)) 

INSERT INTO #SearchItem VALUES 
('sustainable'), 
('sustainability'), 
('conservation'), 
('environmental'), 
('environmentally') 

SELECT TOP 5 * 
FROM NewsArticles as n 
JOIN #SearchItem as s 
ON n.headline COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' OR 
n.body COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' 
ORDER BY n.publishDate DESC 

Điều này dường như làm việc rất tốt cho hiệu suất, nhưng dường như đôi khi mang lại điều trùng lặp mà một trong các từ tìm kiếm xuất hiện trong cả cơ thể và tiêu đề (thường là trường hợp). Tôi đã thử sử dụng từ này bằng cách sử dụng 'SELECT DISTINCT TOP 5 *' nhưng điều này cho tôi một lỗi nói 'Loại dữ liệu ntext không thể được chọn là DISTINCT vì nó không thể so sánh được'. Có phải dừng việc này từ việc mang lại các bản sao mà không thực hiện 2 tìm kiếm riêng biệt và sử dụng UNION không?

+0

Tại sao nên sử dụng *? Bạn có cần cột ntext không? – Paparazzi

+1

Đôi '%' trong câu lệnh 'like' của bạn là một trong những thủ phạm chính ... Bạn có cần thông tin này được cập nhật trong (gần) thời gian thực không? Nếu không, bạn có thể có một bảng tra cứu với 'articleID' (bài viết của bạn có ID của một số loại, tôi giả sử?) Và cờ cho' is_sustainable', 'is_conservation', v.v. Sau đó, bạn có thể có một công việc hàng loạt sẽ chèn các hàng mới vào bảng này, nhập các cờ chính xác thông qua các câu lệnh 'like'. Sau đó, chỉ cần tham gia vào bảng tra cứu này và sử dụng các cờ thích hợp. –

+0

Tôi nghĩ rằng vấn đề với các bản sao phát sinh khi có một trận đấu trên nhiều từ, không phải là một trận đấu hoặc tiêu đề và cơ thể – SWeko

Trả lời

1

Kể từ khi bạn nhận được nhiều lượt truy cập vào nhiều từ, bạn có thể sử dụng của chọn ID như một bộ lọc để lựa chọn thực tế các bài viết:

Select TOP 5 * 
from NewsArticles 
where ID in (SELECT ID 
    FROM NewsArticles as n 
    JOIN #SearchItem as s 
    ON n.headline COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' OR 
     n.body COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' 
) 
ORDER BY publishDate DESC 

Nó vẫn phải nhanh chóng hợp lý (so với truy vấn gốc) và không bị trùng lặp.

(như trong phản ứng Rawheiser, có một giả định rằng một trường ID thực sự tồn tại :))

+0

giải pháp rất đẹp. Hoạt động tốt nhờ! – sr28

2

Nếu có một chìa khóa tin tức Điều bạn có thể sử dụng một truy vấn để mà tham gia trở lại với chính nó như:

select top 5 * 
from NewsArticles as na 
join 
    ( 
     SELECT distinct idNo , publishDate 
     FROM NewsArticles as n 
     JOIN #SearchItem as s 
     ON n.headline COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' OR 
     n.body COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %' 
    ) as sk 
     on sk.idNo = na.idNo 
ORDER BY sk.publishDate DESC 
+0

Cảm ơn nhưng trong khi truy vấn hoạt động, nó mất quá nhiều thời gian để chạy (23 giây). Tuy nhiên, nó nhanh hơn bản gốc của tôi :) – sr28

+0

Như mọi khi, với lời khuyên - "số dặm của bạn có thể thay đổi". – Rawheiser

4

Nếu bạn đang làm các loại tìm kiếm, bạn nên sử dụng tìm kiếm văn bản đầy đủ. Bạn cần phải đọc trong BOL về cách thiết lập điều này vì nó phức tạp. Tuy nhiên khi bạn có một ký tự đại diện là ký tự đầu tiên, thì máy chủ SQL không thể sử dụng các chỉ mục đó là lý do tại sao điều này là chậm.

+0

BOL là gì và những gì là upas? –

+0

BOL là Sách trực tuyến là sự trợ giúp của SQL Server. Upas là lỗi đánh máy cho số lượng – HLGEM

+0

BOL cho chúng tôi nghĩa là Thợ ống nước khởi động –

1

Bạn cũng có thể thử Tìm kiếm toàn văn bản. Một cái gì đó như

SELECT TOP 5 * FROM NewsArticles 
WHERE CONTAINS((headline,body), 'FORMSOF(INFLECTIONAL, sustainable) OR conservation OR FORMSOF(INFLECTIONAL, environmental)') 

Nhưng, HLGEM cho biết, điều quan trọng là phải đọc khi thiết lập FTS. Chỉ cần tạo chỉ mục cho hai cột đó có thể là đủ vì bạn đang tìm kiếm các từ đơn lẻ, nhưng khi bạn thêm cụm từ bạn muốn bắt đầu chỉnh sửa các từ dừng và bộ ngắt và từ tiếng ồn.

0

tôi sẽ để một cái gì đó như thế này

enter image description here

Tôi muốn chương trình một trường hợp quá trình lập chỉ mục nhạy cảm mà có thể chạy ở đêm, điều đó sẽ:

  • bài viết phân tích, chèn vào SEARCH_TERM bất kỳ từ mới nào tìm thấy
  • chèn vào SEARCH_INDEX một bộ dữ liệu cho biết rằng một arti đã cho cle có một cụm từ tìm kiếm nhất định
  • đánh dấu NEWS_ARTICLE như đã được lập chỉ mục.
  • chạy tiếp theo sẽ chỉ số chỉ có điều THA chưa được idexed

Các truy vấn mẫu có thể được như thế này, và sẽ được thắp sáng nhanh vì bạn sẽ không thể sử dụng LIKE:

select 
    distinct n.headline 
from 
    search_item s 
    join search_index x on (s.id = x.search_item_id) 
    join news_article n on (x.news_article_id = n.id) 
where 
    s.term in ('sustainable','sustainability','conservation', 
       'environmental','environmentally') 

Sau đó, bạn có thể tạo từ đồng nghĩa cho cụm từ tìm kiếm và tạo chế độ xem trả về các cụm từ có từ đồng nghĩa của chúng, nếu bạn muốn thực hiện nhiều tìm kiếm ngữ nghĩa hơn trong tương lai.

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