位图堆扫描性能(Bitmap Heap Scan performance)

2019-09-02 01:14发布

我有一个大的报告表。 位图堆扫描步骤花费超过5秒钟。

有什么我可以做什么? 我将列添加到表,并重新编制,它的使用将有助于指数?

我对数据工会和金额,所以我不回500K记录到客户端。
我使用的Postgres 9.1。
这里解释一下:

 Bitmap Heap Scan on foo_table  (cost=24747.45..1339408.81 rows=473986 width=116) (actual time=422.210..5918.037 rows=495747 loops=1)
   Recheck Cond: ((foo_id = 72) AND (date >= '2013-04-04 00:00:00'::timestamp without time zone) AND (date <= '2013-05-05 00:00:00'::timestamp without time zone))
   Filter: ((foo)::text = 'foooooo'::text)
   ->  Bitmap Index Scan on foo_table_idx  (cost=0.00..24628.96 rows=573023 width=0) (actual time=341.269..341.269 rows=723918 loops=1)

查询:

explain analyze
SELECT CAST(date as date) AS date, foo_id, ....
from foo_table
where foo_id = 72
and date >= '2013-04-04'
and date <= '2013-05-05'
and foo = 'foooooo'

Index def:
Index "public.foo_table_idx"
   Column    |            Type
-------------+-----------------------------
 foo_id      | bigint
 date        | timestamp without time zone

 btree, for table "public.external_channel_report"

表:
footext与4个不同的值的字段。
foo_idbigint与目前10K不同的值。

Answer 1:

创建复合指数(foo_id, foo, date) (以该顺序)。

需要注意的是,如果你选择50万次的记录(以及他们全部返回给客户端),这可能需要很长时间。

你确定你需要在客户端(而非某种聚合或对所有50万条记录LIMIT )?



Answer 2:

回答评论

我是否需要在索引的顺序相同,其中,列?

在表达式中的顺序WHERE子句是完全不相干的 ,SQL是不是程序语言。

修正错误

时间戳列应该被命名为“日期”有几个原因。 显然,这是一个timestamp ,而不是date 。 但更重要的是, date它是一个保留字中的所有SQL标准和Postgres的类型和函数的名称,不应该被用来作为标识。

您应该提供与你的问题正确的信息,包括完整的表定义和有关现有索引确凿信息。 我可能是一个好主意,通过读取开始关于本手册指标一章 。

WHERE上时间戳的条件是最有可能不正确:

and date >= '2013-04-04'
and date <= '2013-05-05'

对于timestamp列的上边界或许应该被排除在外

and date >= '2013-04-04'
and date <  '2013-05-05'

指数

随着多列索引@Quassnoi提供 ,您的查询会很多,因为所有符合条件的行可以从指数的一个连续的数据块被读取。 没有行被白白阅读(取消资格),就像你现在拥有它。
但是,50万行仍需要一段时间。 通常你必须验证的可视性和从表中获取附加列。 一个仅索引扫描 可能是Postgres的一个选项9.2+。

列的顺序最好是这样,因为经验法则是:平等列第一 - 然后范围。 更多的解释,并在链接上dba.SE此相关的答案 。

CLUSTER / pg_repack

你可以根据这个指数通过精简表进一步加快速度,使最低块都从表中读取 - 如果你没有这样的抗衡它的其他要求!

如果你想更快,但是,你可以简化你的表行的物理顺序。 如果你能负担得起以独占方式锁定你的表几秒钟(在例如下班时间),根据该指数重写你的表和订单行:

ALTER TABLE foo_table CLUSTER ON idx_myindex_idx;

如果同时使用是一个问题,考虑pg_repack ,它可以这样做,而不排他锁。

效果:较少的块需要从表中读取,一切都预先排序。 这是一个一次性的效果恶化随着时间的推移,如果你有写在桌子上。 所以,你会不时重新运行时间。

我复制和改编自最后一章对dba.SE此相关的答案 。



文章来源: Bitmap Heap Scan performance