Sql 通过两个表循环的优化方式,其中一个表非常大
基本上,我正在处理来自icu患者的数据,并研究一种特定的疾病。对于每个患者,在患者入住ICU期间,我都有疾病阶段,如您所见: 我的另一个表是记录表: 我只想在记录表中添加疾病的阶段,即进行测量时的阶段,这可以简单地通过records.charttime在timeline.Start和timeline.ends之间进行,但我想以尽可能优化的方式进行,因为记录表有近1亿行,时间线表超过10万行 我读过关于游标的用法,但我不知道在这种情况下使用游标是否有意义,或者我只是增加了复杂性,使用JOIN可以很容易地解决这个问题Sql 通过两个表循环的优化方式,其中一个表非常大,sql,postgresql,date-range,postgresql-performance,Sql,Postgresql,Date Range,Postgresql Performance,基本上,我正在处理来自icu患者的数据,并研究一种特定的疾病。对于每个患者,在患者入住ICU期间,我都有疾病阶段,如您所见: 我的另一个表是记录表: 我只想在记录表中添加疾病的阶段,即进行测量时的阶段,这可以简单地通过records.charttime在timeline.Start和timeline.ends之间进行,但我想以尽可能优化的方式进行,因为记录表有近1亿行,时间线表超过10万行 我读过关于游标的用法,但我不知道在这种情况下使用游标是否有意义,或者我只是增加了复杂性,使用JOIN可以很
最好的解决方案是什么?使用显式游标循环通常比普通连接慢。Postgres将为您执行循环,很可能在查询计划中使用嵌套循环
SELECT r.*, t.stage
FROM records r
LEFT JOIN timeline t ON r.icustay_id = t.icustay_id -- guessing ... ?
AND r.charttime >= t.starts
AND r.charttime < t.ends; -- excl. upper bound
两者之间可能会错误地包含上限
左连接保留记录中的所有行,即使在时间轴中找不到匹配项
我假设时间线中的范围不能重叠?否则,将得到重复的行。表时间表可能有一个排除约束。见:
因为您无论如何都在处理整个表,所以索引不会有多大帮助
然而,由于您的记录表太大,您可能没有足够的内存来处理RAM中的所有内容,所以一次处理记录表的分区可能是值得的。分区的最佳方式取决于未公开的详细信息,最重要的是两个表中行的物理排序顺序。请以纯文本形式提供表定义和示例数据,而不是图像链接。并始终声明您的Postgres版本。考虑下面的说明:您是否试图在记录表中添加一个新列并填充它?或者您只是想在不改变表结构的情况下动态查看联接的结果?我认为联接条件还需要包括timeline.icustay\u id=records.icustay\u id。@jjanes:是的,列名也建议这样做。我加上去了。