这是我的问题:
select word_id, count(sentence_id)
from sentence_word
group by word_id
having count(sentence_id) > 100;
表句子词包含3个字段,wordid,sentenceid和主键id。 它有350k +行。 这个查询花了85秒钟,我想知道(希望,祈祷?)有一种更快的方法可以找到所有超过100个句子的单词。
我已经尝试取出选择计数部分,只是做'有计数(1)',但都没有加速。
我很感激您可以借出任何帮助。谢谢!
答案 0 :(得分:6)
如果您还没有,请在sentence_id,word_id。
上创建复合索引答案 1 :(得分:3)
有计数(sentence_id)> 100;
这有一个问题......表中有重复的单词/句子对,或者它没有。
如果它确实有重复的单词/句子对,您应该使用此代码来获得正确的答案:
HAVING COUNT(DISTINCT Sentence_ID) > 100
如果表没有重复的单词/句子对...那么你不应该计算sentence_ids,你应该只计算行数。
HAVING COUNT(*) > 100
在这种情况下,您可以在 仅限word_id 上创建索引,以获得最佳效果。
答案 2 :(得分:1)
如果经常执行该查询,并且表很少更新,则可以保留一个带有单词ID和相应句子数的辅助表 - 很难想到除此之外的任何进一步优化!
答案 3 :(得分:1)
您的查询很好,但需要一些帮助(索引)才能获得更快的结果。
我手边没有资源(或访问SQL),但我会尽量帮助你。
从概念上讲,回答该查询的唯一方法是计算共享相同word_id的所有记录。这意味着查询引擎需要一种快速的方法来查找这些记录。如果没有word_id上的索引,数据库唯一可以做的就是一次查看一个记录表,并保持运行它找到的每个不同word_id的总数。这通常需要一个临时表,在扫描整个表之前不能发送任何结果。不好。
对于word_id的索引,它仍然必须通过表,所以你会认为它没有多大帮助。但是,SQL引擎现在可以计算每个word_id的计数,而无需等到表的末尾:它可以调度行和word_id值的计数(如果它通过了您的where
子句),或者丢弃行(如果没有);这将导致服务器上的内存负载降低,可能是部分响应,并且不再需要临时表。第二个方面是并行性;使用word_id索引,SQL可以将块分割成块并使用单独的处理器核心并行运行查询(取决于硬件功能和现有工作负载)。
这可能足以帮助您查询;但你必须尝试看看:
CREATE INDEX someindexname ON sentence_word (word_id)
(T-SQL语法;您没有指定您正在使用的SQL产品)
如果这还不够(或根本没有帮助),还有另外两种解决方案。
首先,SQL允许您使用索引视图和其他机制预先计算COUNT(*)。我手边没有细节(我不经常这样做)。如果您的数据不经常更改,那么可以获得更快的结果,但会降低复杂性和存储空间。
此外,您可能需要考虑将查询结果存储在单独的表中。只有当数据永远不会改变,或者在精确的时间表上改变时(例如,在早上2点的数据刷新期间),或者如果它变化很小并且您可以在几小时内获得非完美结果(您必须安排定期数据刷新);这是穷人数据仓库的道德等价物。
确定哪些对您有用的最佳方法是运行查询并查看包含和不包含上述候选索引的查询计划。
答案 4 :(得分:0)
令人惊讶的是,在大型数据集上实现这一目标的速度更快:
SELECT totals.word_id, totals.num
FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
WHERE num > 1000;