我有一个 PostgreSQL 9.3 表,其中包含一些数字和一些附加数据:
CREATE TABLE mytable (
myid BIGINT,
somedata BYTEA
)
Run Code Online (Sandbox Code Playgroud)
该表目前有大约 10M 条记录,占用 1GB 磁盘空间。myid不连续。
我想计算 100000 个连续数字的每个块中有多少行:
SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
Run Code Online (Sandbox Code Playgroud)
这将返回大约 3500 行。
我注意到某个索引的存在显着加快了这个查询,即使查询计划根本没有提到它。没有索引的查询计划:
db=> EXPLAIN (ANALYZE TRUE, VERBOSE TRUE) SELECT myid/100000 AS block, count(*) AS total FROM mytable GROUP BY myid/100000;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=1636639.92..1709958.65 rows=496942 width=8) (actual time=6783.763..8888.841 rows=3460 loops=1)
Output: ((myid / 100000)), count(*)
-> Sort (cost=1636639.92..1659008.91 rows=8947594 width=8) (actual time=6783.752..8005.831 …Run Code Online (Sandbox Code Playgroud) 在 PostgreSQL 9.3 中,我试图在一个很少使用的(占总记录的 0.00001%)布尔列上创建一个有效的索引。为此,我在 SO 上发现了这篇文章: https //stackoverflow.com/a/12026593/808921
我正在尝试利用 Erwin Brandstetter 推荐的 PostgreSQL 的“部分索引”功能。我已经有一个包含几百万条记录的表,我想将索引添加到该表中,如下所示:
CREATE INDEX schema_defs_deprovision ON schema_defs (deprovision)
WHERE deprovision = 0;
Run Code Online (Sandbox Code Playgroud)
(绝大多数记录都会有 deprovision = 1)
问题是,当我尝试将此索引与最简单的查询一起使用时,PostgreSQL 就好像它不存在一样:
explain select * from schema_defs where deprovision = 0;
Seq Scan on schema_defs (cost=0.00..1.05 rows=1 width=278)
Filter: (deprovision = 0)
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是,我发现如果这个索引是在表中有数据之前创建的,那么它确实可以正常工作。不相信我?以下是一些证明这一点的 SQL Fiddle 条目:
插入后创建的部分索引(索引不起作用)
插入前创建的部分索引(索引正常工作)
在这两个中,只需展开“查看执行计划”链接即可查看我在说什么。
所以,我的问题是 - 我必须做什么才能让 PostgreSQL 在创建索引之前开始在其中包含数据的表上使用部分索引?
顺便说一句,我也是 SQL Fiddle 的开发人员,这个问题与我正在为此进行的一项新开发工作有关。
语境:
PostgreSQL 10,users表有3667438条记录,users表有一个名为social的JSONB,我们通常使用对计算函数输出进行索引的策略,这样我们就可以将信息聚合到一个单独的索引中。的输出engagement(social)函数是双精度数字类型。
问题:
有问题的条款是 ORDER BY engagement(social) DESC NULLS LAST,还有一个 btree 索引idx_in_social_engagement with DESC NULLS LAST附加到这个数据。
快速查询:
EXPLAIN ANALYZE
SELECT "users".* FROM "users"
WHERE (follower_count(social) < 500000)
AND (engagement(social) > 0.03)
AND (engagement(social) < 0.25)
AND (peemv(social) < 533)
ORDER BY "users"."created_at" ASC
LIMIT 12 OFFSET 0;
Limit (cost=0.43..52.25 rows=12 width=1333) (actual time=0.113..1.625
rows=12 loops=1)
-> Index Scan using created_at_idx on users (cost=0.43..7027711.55 rows=1627352 width=1333) (actual time=0.112..1.623 rows=12 loops=1)
Filter: ((follower_count(social) < 500000) AND …Run Code Online (Sandbox Code Playgroud) postgresql performance order-by postgresql-10 postgresql-performance