【问题标题】:where like over varchar(500)在哪里喜欢 varchar(500)
【发布时间】:2010-10-12 16:41:22
【问题描述】:

我有一个查询,当我在 where 部分添加添加时,它的速度会大大降低

本质上只是对 varchar(500) 字段的类似查找

在哪里...

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

我一直在绞尽脑汁,但是当我添加它时,查询速度几乎变慢了。

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

任何帮助表示赞赏。

sql 2000 企业版。

这里有一些附加信息:

哎呀。不幸的是,作为一些背景,我确实需要(在 like 声明的情况下)将 % 放在前面。 背后有我无法回避的业务逻辑。

我已经在该字段上创建了一个全文目录,这给我带来了问题 并将搜索转换为使用 contains 语法。

不幸的是,虽然这有时会提高性能,但对于新词搜索来说似乎很慢(较慢)。 因此,如果我有苹果.. 苹果在随后的时间里似乎更快,但对于新的橙色搜索却没有(例如)。

所以我不认为我可以这样做(除非你可以建议一些修补以使其更加一致)。

附加信息:

该表仅包含大约 60k 条记录 我要过滤的字段是 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))

这可能是我对如何让全文搜索目录正常工作缺乏了解。

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

【问题讨论】:

  • 请提供更多关于表结构、表中数据等的信息。

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


【解决方案1】:

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

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

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

【讨论】:

  • 还值得注意的是,他必须使用全文搜索语法而不是 LIKE 才能利用这一点。
  • 从技术上讲,LIKE 不是问题所在。更有可能的是,在搜索模式的开头使用了% 通配符。
  • 嗨,这些都是非常好的建议/cmets 非常感谢。
【解决方案2】:

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

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

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

无论有没有全文索引,一件事都可能有所帮助:您能否缩小正在搜索的行的范围,因此至少 SQL 不需要扫描 整个 表,但是只是其中的一部分?

【讨论】:

    【解决方案3】:

    “% blahblah %”是提高性能的问题。将通配符放在开头告诉 SQL Server 字符串可以以任何合法字符开头,因此它必须扫描整个索引。如果您必须拥有此过滤器,最好的选择是专注于您的其他过滤器以进行改进。

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

        那么问题就变成了,您真的需要在相关列中的任何位置搜索给定的文本字符串吗?

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

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

        【讨论】:

          【解决方案6】:

          我不认为这是一个有效的答案,但我想把它扔给一些更有经验的海报cmets......这些是等价的吗?

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

          对比

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

          据我所知,这从数据库逻辑的角度来看是等效的,因为它强制执行相同的扫描。试试看不会有什么坏处吧?

          【讨论】:

          • 从 I/O 的角度来看,它们应该是相同的。不知道一个在 CPU 方面是否会比另一个更高效。
          猜你喜欢
          • 1970-01-01
          • 2021-01-27
          • 2014-07-11
          • 2021-09-03
          • 2010-09-30
          • 2021-11-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多