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结构如下:
我想知道一些事情:
- 这是编写 SQL 查询的有效方法吗
- 我是否应该将“trade_date”和“ticker”的索引添加到 table 结构
- 切换到 pandas 会有帮助吗,因为 table 会随着时间的推移而变大
谢谢
编辑:
添加想要的结果:
因此,例如,在 21 年 9 月 17 日,前几天 table 中没有一些代码(以红色突出显示)[=36] =]
您正在选择子查询中的所有结果,这会在您的 RDBMS 内存中生成大量数据,并与您的值进行比较。您应该使用 LEFT JOIN
和 WHERE
子句,如下所示:
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)
上的索引,这应该快得令人眼花缭乱了。
我在 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结构如下:
我想知道一些事情:
- 这是编写 SQL 查询的有效方法吗
- 我是否应该将“trade_date”和“ticker”的索引添加到 table 结构
- 切换到 pandas 会有帮助吗,因为 table 会随着时间的推移而变大 谢谢
编辑:
添加想要的结果:
因此,例如,在 21 年 9 月 17 日,前几天 table 中没有一些代码(以红色突出显示)[=36] =]
您正在选择子查询中的所有结果,这会在您的 RDBMS 内存中生成大量数据,并与您的值进行比较。您应该使用 LEFT JOIN
和 WHERE
子句,如下所示:
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)
上的索引,这应该快得令人眼花缭乱了。