在over varchar(500)的地方

时间:2010-10-12 16:41:22

标签: sql sql-server tsql sql-server-2000

我有一个查询,当我在部分

添加一个附加内容时,它会大大减慢

基本上就像在varchar(500)字段上查找一样

其中...

和(xxxxx.yyyy喜欢'%blahblah%')

我一直在绞尽脑汁,但是当我添加它时,查询的速度非常慢。

我想知道是否有人在更改字段类型,索引设置或索引提示或可能有帮助的内容方面有建议。

任何帮助表示感谢。

sql 2000 enterprise。

这里有一些额外的信息:

糟糕。作为一些背景,不幸的是我需要(在类似声明的情况下)在前面有%。 背后有商业逻辑,我无法避免。

我已经在该字段上创建了一个全文目录,这导致了我的问题 并将搜索转换为使用包含语法。

不幸的是,虽然这有时会增加性能,但对于新单词搜索来说似乎很慢(较慢)。 所以,如果我有苹果..苹果似乎在随后的时间更快,但不是橙色的新搜索(例如)。

所以我不认为我可以接受(除非你可以提出一些修改以使其更加一致)。

其他信息:

该表仅包含大约6万条记录 我想要过滤的字段是varchar(500) Windows Server 2003上的sql 2000

我正在使用的查询肯定是错综复杂的

抱歉,我不得不更换专有的东西..但应该给你并指出查询:

SELECT TOP 99 AAAAAAAA.Item_ID, AAAAAAAA.CatID, AAAAAAAA.PID, AAAAAAAA.Description, 
AAAAAAAA.Retail, AAAAAAAA.Pack, AAAAAAAA.CatID, AAAAAAAA.Code, BBBBBBBB.blahblah_PictureFile AS PictureFile, 
AAAAAAAA.CL1, AAAAAAAA.CL1, AAAAAAAA.CL2, AAAAAAAA.CL3 
FROM CCCCCCC INNER JOIN DDDDDDDD ON CCCCCCC.CID = DDDDDDDD.CID 
INNER JOIN AAAAAAAA ON DDDDDDDD.CID = AAAAAAAA.CatID LEFT OUTER JOIN BBBBBBBB 
ON AAAAAAAA.PID = BBBBBBBB.Product_ID INNER JOIN EEEEEEE ON AAAAAAAA.BID = EEEEEEE.ID 
WHERE 
(CCCCCCC.TID = 654321) AND (DDDDDDDD.In_Use = 1) AND (AAAAAAAA.Unused = 0) 
AND (DDDDDDDD.Expiry > '10-11-2010 09:23:38')  AND 
(
    (AAAAAAAA.Code = 'red pen') OR 
        ( 
            (my_search_description LIKE '% red %') AND (my_search_description LIKE '% nose %')  
            AND (DDDDDDDD.CID IN (63,153,165,305,32,33))
         )
)
AND (DDDDDDDD.CID IN (20,32,33,63,64,65,153,165,232,277,294,297,300,304,305,313,348,443,445,446,447,454,472,479,481,486,489,498)) 
ORDER BY AAAAAAAA.f_search_priority DESC, DDDDDDDD.Priority DESC, AAAAAAAA.Description ASC

你可以看到抛出my_search_description过滤器还包括一个dddd.cid过滤器(业务逻辑)。

这是减慢速度的部分(从我的页面的1.5-2秒加载到6-8秒的负载(ow ow ow))

可能是我对如何使全文检索catelogue工作缺乏了解。

答案给我留下了非常深刻的印象,所以如果有人有任何提示,我会非常感激。

6 个答案:

答案 0 :(得分:8)

如果您还没有,请启用全文索引。

不幸的是,在查询中使用LIKE子句确实会减慢速度。全文索引实际上是我所知道的加速速度的唯一方式(当然是以存储空间为代价)。

这是指向Full-Text Search in SQL Server概述的链接,它将向您展示如何配置内容并更改查询以利用全文索引。

答案 1 :(得分:4)

更多细节肯定会有所帮助,但是......

全文索引当然很有用(取决于有关表和查询的更多详细信息)。全文索引在设置和查询中需要一些额外的工作,但这是尝试进行有效搜索的那种搜索的唯一方法。

以通配符开头的LIKE问题是SQL服务器必须执行完整的表扫描才能找到匹配的记录 - 不仅需要扫描每行,而且它必须读取您正在查询的基于字符的字段的内容。

有或没有全文索引,有一件事可能会有所帮助:你可以缩小搜索行的范围,所以至少SQL不需要扫描整个表,但是只是它的一部分?

答案 2 :(得分:3)

'%blahblah%'是改善表现的问题。将通配符放在开头告诉SQL Server该字符串可以以任何合法字符开头,因此它必须扫描整个索引。如果您必须使用此过滤器,最好的选择是专注于其他过滤器以进行改进。

答案 3 :(得分:2)

在搜索模式的开头使用带有通配符的LIKE会强制服务器扫描每一行。它无法使用任何索引。索引从左到右工作,由于左侧没有常量,因此不使用索引。

从WHERE子句看,您似乎在尝试查找条目中存在特定单词的行。如果您正在搜索整个单词,那么全文索引可能是您的解决方案。

全文索引为指定列中包含的每个单词创建索引条目。然后,您可以快速查找包含特定单词的行。

答案 4 :(得分:0)

正如其他海报正确指出的那样,在LIKE表达式中使用通配符%会导致生成使用SCAN操作的查询计划。扫描操作接触表或索引中的每一行,具体取决于正在执行的扫描操作的类型。

所以问题真的变成了,你真的需要在相关列中的任何地方搜索给定的文本字符串吗?

如果不是,很好,问题已经解决,但如果它对您的业务逻辑至关重要,那么您有两种优化路径。

  1. 通过将优化工作重点放在剩余的搜索参数上,真的可以提高查询的整体选择性。
  2. 实施全文索引解决方案。

答案 5 :(得分:0)

我认为这不是一个有效的答案,但我想把它扔到那里以获得一些更有经验的海报评论......这些是否相同?

where (xxxxx.yyyy like '% blahblah %')

vs

where patindex(%blahbalh%, xxxx.yyyy) > 0

据我所知,从数据库逻辑的角度来看,这是相当的,因为它强制进行相同的扫描。猜猜尝试不会受伤?