PostgreSQL 12 对比Pandas 子查询优化

PostgreSQL 12 Vs. Pandas Sub Query Optimization

我在 PostgreSQL 中有一个 table,我想 select 任何新的“代码”值,这些值不在 table 之前的“ trade_date".

以下查询 运行 需要 1 分钟,table 包含大约 56k 行:

SELECT DISTINCT a.trade_date, a.ticker, a.company_name
FROM t_ark_holdings a
WHERE a.ticker NOT IN (
                        SELECT b.ticker FROM t_ark_holdings b WHERE b.trade_date <a.trade_date
                        )
ORDER BY a.trade_date DESC, a.ticker, a.company_name

我的table结构如下:

我想知道一些事情:

  1. 这是编写 SQL 查询的有效方法吗
  2. 我是否应该将“trade_date”和“ticker”的索引添加到 table 结构
  3. 切换到 pandas 会有帮助吗,因为 table 会随着时间的推移而变大 谢谢

编辑: 添加想要的结果:

因此,例如,在 21 年 9 月 17 日,前几天 table 中没有一些代码(以红色突出显示)[=36] =]

您正在选择子查询中的所有结果,这会在您的 RDBMS 内存中生​​成大量数据,并与您的值进行比较。您应该使用 LEFT JOINWHERE 子句,如下所示:

SELECT a.trade_date, a.ticker, a.company_name
FROM t_ark_holdings a
LEFT JOIN t_ark_holdings b
ON a.ticker = b.ticker and b.trade_date < a.trade_date
WHERE b.ticker IS NULL
ORDER BY a.trade_date DESC, a.ticker, a.company_name

此查询假设询问任何 b 具有与 ticker a 相同但日期更早的记录,并且 WHERE 子句检查它是否存在并且仅在不包含结果时包含结果。请注意,我删除了 DISTINCT 关键字,假设您在同一日期的最新发现中不会有多个 ticker 值。如果查询仍然很慢,那么您可能需要一个索引。尝试创建索引并比较性能与没有索引的性能。

要说明的另一点是您谈到了上一个交易日期。如果那是一个已知的日期或日期范围,那么您可以进一步检查 b 是否在该 date/date 范围内。

如果您想要每个 ticker/company_name 的第一行,请使用 distinct on:

select distinct on (a.ticker, a.company_name) a.*
from t_ark_holdings a
order by a.ticker, a.company_name, a.trade_date;

有了 (ticker, company_name, trade_date) 上的索引,这应该快得令人眼花缭乱了。