如果使用索引进行查询,PostgreSQL 将不会使用索引进行投影



我一直在进行一些实验,标题中的语句似乎是正确的,我想知道是否有解决方案。

这是一个示例:

CREATE TABLE test ( cond text, v1 integer, v2 integer, v3 integer );
-- Insert millions of rows
CREATE INDEX cond_idx ON test (cond);
CREATE INDEX values_idx ON test (v1, v2, v3);
VACUUM ANALYZE test;

运行这些查询:

-- Uses Index Only Scan on values_idx for projection
SELECT sum(v1), sum(v2), sum(v3) FROM test;
-- Uses Bitmap Index Scan on cond_idx then a Bitmap Heap Scan
-- This is undesirable as it doesn't rely exclusively on indexes
SELECT sum(v1), sum(v2), sum(v3) FROM test WHERE cond = '123';

PostgreSQL可以有效地结合索引,但似乎仅适用于复合条件,有没有办法让PostgreSQL使用索引进行投影,因为它使用一个或多个来查找所需的行?

自动响应将是创建具有所有4列的单个索引。问题是这个简约的例子。在现实世界的情况下,将通过不同的列来查询同一表,要求每个需要的查询条件多列索引。

更新:将计数更改为总和,以使示例更容易理解。还添加了更多的"值"列。

count()聚合无法将索引数据用作输入,因为它计数1对于每个非零值:http://www.postgresql.org/docs/9.4/9.4/static/static/functions-functions-functions-functions-functions-functions-gracregate.html

count(expression): 
    number of input rows for which the value of expression is not null

在第二个查询中,索引过滤后,我们不知道哪一行具有null value列。

您只需要在索引中添加相关数据并使用多列索引即可。

CREATE INDEX cond_value_idx ON test (cond, value);

一旦您阅读了出色的http://use-the-index-luke.com/

,这可能会变得清晰

这是一个比喻,可以更好地了解PostgreSQL的内部设备。您有1000本普通书籍和2本"特殊"书籍。1000本书是您的行,另外两个是您的索引。

一本索引书列出了每个书架和按主题分类的书架,另一本书列出了每个书架和数字,但由作者分类。

请注意,1000本书存储在一个巨大的架子上,并且两本索引书坐在您的桌子上,可以使用。

问题在于,有些书是如此独特,以至于它们不按主题进行分类(我们的零值)。

如果要计算与主题相关的书籍,则只需要选择"主题"索引即可。但是,如果您想计算每个与主题相关的格雷戈里·史密斯(Gregory Smith)的书,那么您将查找Gregory Smith书籍的作者索引,然后在架子上捡起它们以查看它们是否具有主题。

这里的解决方案是第三本索引书,它列出了由作者和主题分类的每个书架和数字。只有这样,您就可以立即回答这个问题,而无需进入架子。

请注意,多列指数的顺序很重要,因为您无法通过主题分类的索引书,然后由作者轻松回答相同的问题。

最新更新