你的查询很好,但它需要一些帮助(索引)来获得更快的结果。
我没有手头资源(或访问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点的数据刷新期间),或者如果数据变化很小,并且几个小时内您可以忍受非完美的结果(您将不得不安排定期数据刷新);这就是穷人数据仓库的道德等价物。
确定什么适合您的最好方法是运行查询并查看带有和不带有一些候选索引的查询计划。
哪些DBMS您使用的? – 2009-05-04 05:56:04
这是与MySQL(并使用HeidiSQL作为客户端访问它) – Jeff 2009-05-04 21:30:53
另一个恼人的澄清...(对不起):数据不断变化。约10k插入行/天和〜5k删除行。所以我认为这使得存储或缓存结果不可能 – Jeff 2009-05-04 21:47:38