【问题标题】:improve performance union all+group by+order by+count提高性能 union all+group by+order by+count
【发布时间】:2012-04-10 10:56:31
【问题描述】:

我有一张表:items(id,description)。在我的程序中,我得到一个单词列表(word1 到 wordN)作为输入,我需要计算这些单词中有多少出现在表中的每个描述中,并根据该数字对结果进行排序。这是我的解决方案,但我欢迎有关如何提高性能的建议。谢谢。

SELECT x, COUNT(*) 
FROM (SELECT description as x, id FROM items where description LIKE '%word1%'
      UNION ALL
      SELECT description as x, id FROM items where description LIKE '%word2%'
      UNION ALL
       ...
      UNION ALL
      SELECT description as x, id FROM items where description LIKE '%wordN%')
GROUP BY (id)
ORDER BY COUNT(*) DESC

【问题讨论】:

    标签: sql group-by sql-order-by union-all


    【解决方案1】:

    如果您查看执行计划,您可能会看到对您联合在一起的每个 SELECT 进行单独的表扫描。当您使用该术语的通配符前缀进行搜索时,这意味着该查询是不可分割的 - 因此即使描述列上有索引,它也无法使用它,因此会进行扫描。

    通过将条件组合为一个,您可以只扫描一次表,而不是 n 次:

    SELECT description as x, id 
    FROM items 
    WHERE description LIKE '%word1%'
        OR description LIKE '%word2%'
        OR description LIKE '%wordn%'
    

    现在运行它应该会向您显示一个带有单个表扫描的执行计划,因此它在一次扫描中进行匹配。

    但是,您的原始查询略有不同,因为它似乎根据项目匹配的这些术语的数量对结果进行排名。因此,出于性能和功能的原因,可能值得研究Full Text Search

    【讨论】:

    • +1 我认为文本索引是提高这只小狗性能的唯一方法,除非可以选择并行查询。
    • 谢谢。我以前很怕那个。我来看看 FTS。
    【解决方案2】:
    SELECT x, COUNT(*) 
    FROM (SELECT description as x, id FROM items where description LIKE '%word1%' 
           or description LIKE '%word2%'
           or description LIKE '%wordN%')
    GROUP BY (id)
    ORDER BY COUNT(*) DESC
    

    这样应该更好……

    【讨论】:

    • 这会产生不同的结果集:如果两个单词与一个描述匹配,则原始查询将计为 2,而您的将计为 1。
    猜你喜欢
    • 2019-01-27
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多