【问题标题】:very slow count with 7 million rows700 万行的计数非常慢
【发布时间】:2011-11-03 06:22:49
【问题描述】:

我在一个表中有超过 700 万行,并且

SELECT COUNT(*) FROM MyTable where MyColumn like '%some string%'

给我 20,000 行,耗时超过 13 秒。

该表在 MyColumn 上有 NONCLUSTERED INDEX。

有什么办法可以提高速度?

【问题讨论】:

  • 唉,%substring% 即使使用索引也无法真正有效……但是,如果您正在寻找相邻的单词,那么全文索引可能会有所帮助。
  • 您使用LIKE 子句的事实意味着无论如何它都必须处理每一行
  • 将 LIKE 运算符与前导 % 一起使用可以有效地使任何索引无效。如果您要搜索LIKE 'something%',则应使用该索引,它应该快很多
  • 您尝试使用SELECT COUNT(*) 然后使用SELECT * 然后您又尝试SELECT COUNT(*) 吗?可能是您的结果仍然缓存在内存中。使用LIKE '%something%' 将导致您的索引被忽略,因此无论如何它都必须读取整个表,因此人们会期望SELECT * 的性能与SELECT COUNT(*) 相同

标签: sql sql-server performance count


【解决方案1】:

前导通配符搜索 can not 使用 T-SQL 进行优化,不会使用索引

查看 SQL Server 的full text search

【讨论】:

    【解决方案2】:

    您可以尝试full-text search,或Lucene 等文本搜索引擎。

    【讨论】:

      【解决方案3】:

      先尝试使用二进制排序规则,这将意味着复杂的 Unicode 规则被简单的字节比较所取代。

      SELECT COUNT(*) 
      FROM MyTable 
      WHERE MyColumn COLLATE Latin1_General_BIN2 LIKE '%some string%'
      

      另外,请查看由 Erland Sommarskog 撰写的 SQL Server MVP Deep Dives 中标题为“构建您自己的索引”的章节

      基本思想是您向用户引入一个限制,并要求字符串长度至少为三个连续字符。接下来,您从 MyColumn 字段中提取所有三个字母序列,并将这些片段与它们所属的 MyTable.id 一起存储在一个表中。在查找字符串时,您也将其拆分为三个字母片段,并查找它们属于哪个记录 id。这样,您可以更快地找到匹配的字符串。简而言之,这就是策略。

      本书描述了实现细节和进一步优化的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-14
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多