") 运算符-6ren"> ") 运算符-我正在尝试利用 PostgreSQL 中的多列 btree 索引来执行两个表之间令人讨厌的连接。 Table "revision_main" Column -6ren">
gpt4 book ai didi

sql - PostgreSQL 多列索引连接与比较 ("<"和 ">") 运算符

转载 作者:行者123 更新时间:2023-11-29 11:33:56 26 4
gpt4 key购买 nike

我正在尝试利用 PostgreSQL 中的多列 btree 索引来执行两个表之间令人讨厌的连接。

               Table "revision_main"
Column | Type | Modifiers
----------------+------------------------+-----------
revision_id | integer |
page_id | integer |

Indexes:
"revision_main_pkey" UNIQUE, btree (revision_id)
"revision_main_cluster_idx" btree (page_id, "timestamp") CLUSTER

此表包含对 wiki 中页面的修订(约 3 亿行)。我的表中还有更多列,但在本示例中我已将它们丢弃,因为它们无关紧要。

               Table "revert"
Column | Type | Modifiers
--------------------+---------+-----------
page_id | integer |
revision_id | integer |
reverted_to | integer |
Indexes:
"revert_page_between_idx" btree (page_id, reverted_to, revision_id) CLUSTER

此表包含还原修订(约 2200 万行)。如果修订已被还原,则 revision_id 将在 revision_main 表中有一行,其 revision_id 将介于 reverted_to 和 revision_id 之间,并共享相同的 page_id。 (如果您好奇,请参阅 http://en.wikipedia.org/wiki/Wikipedia:Revert。)

连接这两个表以获得恢复的修订似乎很简单。这是我想出的:

explain SELECT
r.revision_id,
rvt.revision_id
FROM revision_main r
INNER JOIN revert rvt
ON r.page_id = rvt.page_id
AND r.revision_id > rvt.reverted_to
AND r.revision_id < rvt.revision_id;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Merge Join (cost=4202878.87..15927491478.57 rows=88418194298 width=8)
Merge Cond: (r.page_id = rvt.page_id)
Join Filter: ((r.revision_id > rvt.reverted_to) AND (r.revision_id < rvt.revision_id))
-> Index Scan using revision_main_page_id_idx on revision_main r (cost=0.00..9740790.61 rows=223163392 width=8)
-> Materialize (cost=4201592.06..4536465.21 rows=26789852 width=12)
-> Sort (cost=4201592.06..4268566.69 rows=26789852 width=12)
Sort Key: rvt.page_id
-> Seq Scan on revert rvt (cost=0.00..438534.52 rows=26789852 width=12)

即使恢复时的聚集索引应该是 Btree 索引(因此支持比较运算符,如“<”和“>”),查询优化器不会使用索引进行连接,并且“解释”会预测总成本超过 150 亿(明年可能完成)。

是否无法将比较运算符用于多列(btree)索引?我只是做错了吗?

最佳答案

看起来优化器比您更了解它的工作。

如果您选择的不仅仅是表的一小部分(这部分取决于硬件,比如说 5%),那么选择和排序整个表比使用索引更快。如果您只是选择几行,那么它应该使用索引。因此它为您的数据提供了正确的查询计划。

至于总成本,这些数字都是废话,只有在单个查询中相互比较时才有用。 (两个非常相似的查询产生的总成本可能在非常不同的规模上。)执行时间和查询成本几乎无关。

关于sql - PostgreSQL 多列索引连接与比较 ("<"和 ">") 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4891172/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com