Postgres 上的索引

Posted

技术标签:

【中文标题】Postgres 上的索引【英文标题】:Indexing on Postgres 【发布时间】:2021-04-26 06:55:29 【问题描述】:

我有一种对 Postgres 数据库的请求。我有以下查询正在运行并产生大量成本:

从 B2BBP_INDEX_SYNC 中选择 MESSAGEID、INDEX_NAME、OPERATION、ADDED,其中 INDEX_NAME = $1 order by added asc

现在我有 INDEX_NAME 列的索引,但由于最后有 order by,我的索引没有从创建索引中获得任何命中。有没有办法在 Postgres 中管理这种情况?

这是执行计划:

"Gather Merge  (cost=10575980.59..14212080.65 rows=31164396 width=113)"
"  Workers Planned: 2"
"  ->  Sort  (cost=10574980.57..10613936.06 rows=15582198 width=113)"
"        Sort Key: added"
"        ->  Parallel Seq Scan on b2bbp_index_sync  (cost=0.00..5837409.47 rows=15582198 width=113)"
"              Filter: ((index_name)::text = 'B3P_SEARCH_INDEX_DIRECTORY'::text)"
同时添加分析:

"Gather Merge  (cost=10575982.01..14212082.77 rows=31164402 width=113) (actual time=104236.195..115849.741 rows=37399386 loops=1)"
"  Workers Planned: 2"
"  Workers Launched: 2"
"  ->  Sort  (cost=10574981.98..10613937.48 rows=15582201 width=113) (actual time=102579.407..105452.466 rows=12466462 loops=3)"
"        Sort Key: added"
"        Sort Method: external merge  Disk: 1624864kB"
"        Worker 0:  Sort Method: external merge  Disk: 1551568kB"
"        Worker 1:  Sort Method: external merge  Disk: 1581024kB"
"        ->  Parallel Seq Scan on b2bbp_index_sync  (cost=0.00..5837410.51 rows=15582201 width=113) (actual time=0.468..73882.771 rows=12466462 loops=3)"
"              Filter: ((index_name)::text = 'B3P_SEARCH_INDEX_DIRECTORY'::text)"
"Planning Time: 0.079 ms"
"Execution Time: 117928.196 ms"

【问题讨论】:

你也可以分享你的执行计划吗? “b2bbp_index_sync 上的序列扫描(成本=0.00..6110066.54 行=37397083 宽度=113)”“过滤器:((index_name)::text = 'B3P_SEARCH_INDEX_DIRECTORY'::text)”似乎不是使用任何索引... 最好用一个漂亮的格式来质疑该执行计划,这会有所帮助 刚刚更新了最初的问题。感谢您的提醒。 "排序方法:外部合并磁盘:1624864kB"。磁盘排序占用 99% 的时间,尝试添加 1G 或 2G 更多内存(work_mem)。磁盘排序是你能做的最慢的事情。 【参考方案1】:

如果 $1 中指定的值被很多行(超过 5% 的 DB)使用,Postgres 通常会决定进行 SeqScan(读取整个表)而不是从索引(这有点道理,因为索引基本上会告诉 PG 无论如何都要读取整个表)。

您也可以在查询中添加 EXPLAIN ANALYZE 语句吗?它可以帮助我们进一步调试。

【讨论】:

以上是关于Postgres 上的索引的主要内容,如果未能解决你的问题,请参考以下文章

日期字段上的 Postgres DESC 索引

更新不使用索引 postgres

如果存在多个索引,Postgres 如何选择使用哪个索引?

防止在 Postgres 中为特定查询使用索引

postgres 空间索引

关于 postgres 中的聚集索引