我有一个查询,当我在部分
添加一个附加内容时,它会大大减慢基本上就像在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工作缺乏了解。
答案给我留下了非常深刻的印象,所以如果有人有任何提示,我会非常感激。
答案 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操作的查询计划。扫描操作接触表或索引中的每一行,具体取决于正在执行的扫描操作的类型。
所以问题真的变成了,你真的需要在相关列中的任何地方搜索给定的文本字符串吗?
如果不是,很好,问题已经解决,但如果它对您的业务逻辑至关重要,那么您有两种优化路径。
答案 5 :(得分:0)
我认为这不是一个有效的答案,但我想把它扔到那里以获得一些更有经验的海报评论......这些是否相同?
where (xxxxx.yyyy like '% blahblah %')
vs
where patindex(%blahbalh%, xxxx.yyyy) > 0
据我所知,从数据库逻辑的角度来看,这是相当的,因为它强制进行相同的扫描。猜猜尝试不会受伤?