sql - 优化复杂的 PostgreSQL 查询
问题描述
我正在尝试对几个表进行复杂的 SQL 连接:如下所示。我还包含了一个 dB 模式的图像。
考虑 table_1 -
e_id name
1 a
2 b
3 c
4 d
和 table_2 -
e_id date
1 1/1/2019
1 1/1/2020
2 2/1/2019
4 2/1/2019
这里的问题是性能。从表 2 - 4 中,我们只想要给定 e_id 的最新条目,但因为这些表包含历史数据(~>350 万行),所以速度很慢。我附上了一个示例,说明我们目前如何尝试实现这一目标,但它仅包括“table_1”与“table_x”的一个连接。我们按 e_id 分组并获得它的最大日期。我们考虑这样做的另一种方法是创建一个物化视图并从中提取数据并在一段时间后刷新它。欢迎任何改进。
from fds.region as rg
inner join (
select e_id, name, p_id
from fds.table_1
where sec_type = 'S' AND active_flag = 1
) as table_1 on table_1.e_id = rg.e_id
inner join fds.table_2 table_2 on table_2.e_id = rg.e_id
inner join fds.sec sec on sec.p_id = table_1.p_id
inner join fds.entity ent on ent.int_entity_id = sec.int_entity_id
inner join (
SELECT int_1.e_id, int_1.date, int_1.int_price
FROM fds.table_4 int_1
INNER JOIN (
SELECT e_id, MAX(date) date
FROM fds.table_2
GROUP BY e_id
) int_2 ON int_1.e_id = int_2.fsym_id AND int_1.date = int_2.date
) as table_4 on table_4.e_id = rg.e_id
where rg.region_str like '%US' and ent.sec_type = 'P'
order by table_2.int_price
limit 500;
解决方案
您可以简化此逻辑:
(
SELECT int_1.e_id, int_1.date, int_1.int_price
FROM fds.table_4 int_1
INNER JOIN (
SELECT e_id, MAX(date) date
FROM fds.table_2
GROUP BY e_id
) int_2 ON int_1.e_id = int_2.fsym_id AND int_1.date = int_2.date
) as table_4
至:
(SELECT DISTINCT ON (int_1.e_id) int_1.*
FROM fds.table_4 int_1
ORDER BY int_1.e_id, int_1.date DESC
) table_4
这可以利用上的索引fds.table_4(e_id, date desc)
——并且使用这样的索引可能会很快变坏。
您还需要用于连接和过滤的适当索引。但是,如果没有执行计划,就很难更具体。
推荐阅读
- html - 填充和边距在 Bootstrap 中不起作用
- doparallel - 我想在带有 OpenCl 内核的 GPU 中运行这个简单的重新排序代码。可能吗?
- mysql - MySQL SELECT 用户不购买产品
- sed - 将字符串中的所有文本从某个字符删除到某个字符
- java - IllegalArgumentException:在 scheduleSyncDelayedTask 方法中插件不能为空
- php - 插入数据库时数组到字符串的转换错误
- python - 创建一个循环的最佳方法,将矩阵乘以它的每个元素,然后对结果求和
- python - 节点红色守护进程
- javascript - 如何优化 Google Apps 脚本代码以防止超出最大执行时间?
- java - Kafka Stream 应用程序可以从 Kinesis 流中读取吗?