我有一个搜索功能,看起来像这样的新闻文章(包含超过5个搜索项目):
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
此查询旨在提取与可持续发展相关的前5个新闻报道,并位于我的主要可持续发展主页上。但是,运行需要一段时间,页面加载速度很慢。所以我正在寻找加快速度的方法。有这么多LIKE条款似乎很麻烦,所以我尝试了像这样的JOIN:
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
这似乎对性能非常有效,但似乎有时会带回一些重复的文章,其中一个搜索词出现在正文和标题中(通常就是这种情况)。我尝试使用'SELECT DISTINCT TOP 5 *'这个词,但是这给了我一个错误,'ntext数据类型不能被选为DISTINCT,因为它不具有可比性'。是不是在没有进行2次单独搜索和使用UNION的情况下停止重复这个重复?
答案 0 :(得分:4)
如果您正在进行这些类型的搜索,则应使用全文搜索。您需要在BOL中阅读有关如何设置它的内容,因为它很复杂。但是,当您将通配符作为第一个字符时,SQL Server无法使用索引,这就是为什么这很慢。
答案 1 :(得分:2)
如果有新闻文章密钥,您可以使用查询连接回自身,例如:
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
答案 2 :(得分:1)
由于您在多个单词上获得多次点击,您可以使用所选的ID作为实际选择文章的过滤器:
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
它应该仍然相当快(与原始查询相比)并且无重复。
(正如在Rawheiser的回答中,假设ID字段实际存在:))
答案 3 :(得分:1)
您也可以尝试全文搜索。像
这样的东西SELECT TOP 5 * FROM NewsArticles
WHERE CONTAINS((headline,body), 'FORMSOF(INFLECTIONAL, sustainable) OR conservation OR FORMSOF(INFLECTIONAL, environmental)')
但是,正如HLGEM所说,阅读有关设置FTS的信息非常重要。只需为这两列创建索引就足够了,因为您正在搜索单个单词,但是一旦添加了短语,就要开始编辑停用词和断路器以及干扰词。
答案 4 :(得分:0)
我会这样的事情
我会编写一个不区分大小写的索引过程,该过程将在晚上运行,即:
SEARCH_TERM
中插入找到的任何新单词SEARCH_INDEX
中插入一个元组,该元组表示给定文章具有给定的搜索字词NEWS_ARTICLE
标记为已编入索引。示例查询可以是这样的,并且由于您不会使用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')
稍后您可以为搜索字词创建同义词,并创建一个返回带有同义词的字词的视图,如果您希望将来进行更多的语义搜索。