sql - 使用 SSD 时我应该在 PostgreSQL 上禁用位图扫描吗?
问题描述
当我遇到这些行时,我正在阅读 https://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys :
在这种情况下,PostgreSQL 数据库使用两个操作:位图索引扫描,然后是位图堆扫描。它们大致对应Oracle的INDEX RANGE SCAN和TABLE ACCESS BY INDEX ROWID,有一个重要区别:它首先从索引中获取所有结果(Bitmap Index Scan),然后根据行在堆表中的物理存储位置对行进行排序然后从表中获取所有行(位图堆扫描)。这种方法减少了表上随机访问 IO 的数量。
我突然想到,当我们在 SSD 上使用 Postgres 时,这没有任何意义。分类存储位置的计算可能是一种浪费。因为 SSD 是仅随机访问的设备(如果我没记错的话。)
我也做了一些测试,通过打开/关闭enable_bitmapscan
set enable_bitmapscan to on;
explain analyse select count(distinct myid) from experiment.mytable where name='my_name';
----
QUERY PLAN
Aggregate (cost=63196.06..63196.07 rows=1 width=8) (actual time=668.845..668.846 rows=1 loops=1)
-> Bitmap Heap Scan on mytable (cost=696.41..63110.95 rows=34045 width=82) (actual time=54.967..216.382 rows=178705 loops=1)
Recheck Cond: (name = 'my_name'::text)
Heap Blocks: exact=164942
-> Bitmap Index Scan on mytable_name_visittime_idx (cost=0.00..687.89 rows=34045 width=0) (actual time=28.365..28.365 rows=178705 loops=1)
Index Cond: (name = 'my_name'::text)
Planning time: 1.411 ms
Execution time: 669.576 ms
set enable_bitmapscan to off;
explain analyse select count(distinct myid) from experiment.mytable where name='my_name';
----
QUERY PLAN
Aggregate (cost=68369.46..68369.47 rows=1 width=8) (actual time=585.496..585.497 rows=1 loops=1)
-> Index Scan using mytable_name_visittime_idx on mytable (cost=0.56..68284.34 rows=34045 width=82) (actual time=0.019..126.553 rows=178705 loops=1)
Index Cond: (name = 'my_name'::text)
Planning time: 0.062 ms
Execution time: 585.542 ms
当 enable_bitmapscan 规划器使用 BitmapHeapScan + BitmapIndexScan 时,确实有明显的改进。当禁用它时,计划者只选择 IndexScan。
解决方案
您还可以调整配置,让 PostgreSQL 决定随机 IO 成本是否会超过顺序成本。
将此设置 - random_page_cost更改为postgresql.conf
1.0,相当于seq_page_cost
.
这将告诉 PostgreSQL 随机 IO 的成本等于顺序 IO 的成本。
推荐阅读
- python - NLP - Python - 条件频率分布
- asp.net-mvc - ASP NET MVC 上一页
- php - 如何防止标题在 php mysqli 中重复
- list - 使用 Haskell 上的递归返回给定正整数的元组列表
- http - 即使在重新启动 IDE 后,FLUTTER 中的未定义名称“http”
- markdown - 摆脱 Sphinx 中的“重复标签”警告
- java - maven-shade-plugin 输出带有 shadedArtifactAttached 错误被安装覆盖
- javascript - 如何将嵌套数组转换为简单的打字稿对象
- mongodb - 在 mongodb 集合中的数组中添加元素
- ruby-on-rails - 使用 Ruby 将 MSSQL 生产数据库转储并加载到本地计算机