我想利用PostgreSQL中的多列btree索引在两个表之间执行烦人的连接。PostgreSQL多列索引加入比较(“<" and ">”)运算符
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
此表包含修订版本(约300万行)到维基页面。我的表格中有更多的列,但我已经放弃了这个例子,因为它们应该没有关系。
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)
即使在撤销的聚集索引应该是一个B树索引(从而支持运营商比较喜欢“<”和“>”),查询优化器不使用该指数进行加入,“解释”预测总成本超过150亿(可能会在明年完成)。
比较运算符是否不可用于多列(btree)索引?我只是做错了吗?
我可以看到刚刚排序整个表可能会快于使用索引,但根据我的经验,成本估计往往是执行时间的一致反映。另一方面,我从来没有真正知道这些数字是什么意思,所以我会承认你的理解。你是否建议我应该运行查询并忽略数字? – halfak 2011-02-03 22:09:12
@halfak:让我仔细看看。数据库喜欢用小表开始连接。如果您将(page_id,revision_id)上的索引添加到revision_main中,您可能会得到更有效的查询,这可能是可能的。它也可能更糟。但是,如果失败了,那么让它变得更加高效的唯一方法就是找到一种方法来减少数据量。 “ – btilly 2011-02-03 22:46:32