fab*_*tag 0 sql postgresql postgresql-performance
SELECT DISTINCT options.id, options.foo_option_id, options.description
FROM vehicles
INNER JOIN vehicle_options ON vehicle_options.vehicle_id = vehicles.id
INNER JOIN options ON options.id = vehicle_options.option_id
INNER JOIN discounted_vehicles ON vehicles.id = discounted_vehicles.vehicle_id
WHERE discounted_vehicles.discount_id = 4;
Run Code Online (Sandbox Code Playgroud)
上面的查询返回 2067 行,它在 1.7 秒内在本地运行。我想知道它是否尽可能快,或者我是否可以以某种方式进一步调整它,因为这个数据集会随着时间的推移而快速增长。
我在速度不变的情况下尝试过的事情:
1 - 更改连接顺序,从最小的表连接到最大的表。
2 - 向discounted_vehicles.discount_id 添加索引。
最佳查询取决于缺失的信息。
在典型设置中,这应该快得多:
SELECT id, foo_option_id, description
FROM options o
WHERE EXISTS (
SELECT
FROM discounted_vehicles d
JOIN vehicle_options vo USING (vehicle_id)
WHERE d.discount_id = 4
AND vo.option_id = o.id
);
Run Code Online (Sandbox Code Playgroud)
假设参照完整性,由 FK 约束强制执行,我们可以vehicle从查询中省略表并直接连接discounted_vehicles到vehicle_options。
此外,EXISTS如果每个不同的选项有许多符合条件的行,通常会更快。
理想情况下,您应该拥有多列索引:
discounted_vehicles(discount_id, vehicle_id)
vehicle_options(vehicle_id, option_id)
Run Code Online (Sandbox Code Playgroud)
按此顺序索引列。您可能对vehicle_options提供第二个索引有 PK 约束,但列顺序应该匹配。有关的:
根据实际数据分布,可能会有更快的查询样式。有关的:
更改连接顺序通常是徒劳的。Postgres 重新排序以任何它期望最快的方式加入。(例外情况适用。)相关:
| 归档时间: |
|
| 查看次数: |
2217 次 |
| 最近记录: |