有没有办法明确地告诉 Postgres 查询计划器列是相关的?
Is there a way to explicitly tell the Postgres query planner that columns are dependent?
我有两个这样的 table:
(我的实际 table 不同。我使用这些来简化问题。)
purchases (
item_id,
order_id,
PRIMARY KEY(item_id, order_id)
)
payments (
item_id,
order_id,
payment_id
)
当我发出这样的查询时,我得到的行估计值太低了,因为查询规划器假定 item_id 和 order_id 是独立的:
SELECT *
FROM payments
JOIN purchases USING (item_id, order_id)
我可以使用这样的查询来解决这个问题:
SELECT *
FROM payments a
JOIN purchases b ON a.item_id || a.order_id = b.item_id || b.order_id
但是,这会导致其他方面的效率低下,并且查询规划器对查询进行推理的灵活性较低。
另一种方法是引入一个连接 id 的生成列,但如果它被索引,它会增加 table 的 space 要求,这将等同于先前的方法如果它是虚拟列。
有没有办法告诉查询规划器如何在不进行这些权衡的情况下估计一组列的基数?
我会在两个表上尝试扩展统计:
CREATE STATISTICS purchases_ext (dependencies)
ON item_id, order_id FROM purchases;
ANALYZE purchases;
CREATE STATISTICS payments_ext (dependencies)
ON item_id, order_id FROM payments;
ANALYZE payments;
然后优化器可以在估计中添加一个校正因子。
我有两个这样的 table: (我的实际 table 不同。我使用这些来简化问题。)
purchases (
item_id,
order_id,
PRIMARY KEY(item_id, order_id)
)
payments (
item_id,
order_id,
payment_id
)
当我发出这样的查询时,我得到的行估计值太低了,因为查询规划器假定 item_id 和 order_id 是独立的:
SELECT *
FROM payments
JOIN purchases USING (item_id, order_id)
我可以使用这样的查询来解决这个问题:
SELECT *
FROM payments a
JOIN purchases b ON a.item_id || a.order_id = b.item_id || b.order_id
但是,这会导致其他方面的效率低下,并且查询规划器对查询进行推理的灵活性较低。
另一种方法是引入一个连接 id 的生成列,但如果它被索引,它会增加 table 的 space 要求,这将等同于先前的方法如果它是虚拟列。
有没有办法告诉查询规划器如何在不进行这些权衡的情况下估计一组列的基数?
我会在两个表上尝试扩展统计:
CREATE STATISTICS purchases_ext (dependencies)
ON item_id, order_id FROM purchases;
ANALYZE purchases;
CREATE STATISTICS payments_ext (dependencies)
ON item_id, order_id FROM payments;
ANALYZE payments;
然后优化器可以在估计中添加一个校正因子。