【发布时间】:2021-07-09 02:09:38
【问题描述】:
我需要从表中查找日期,然后使用该值过滤另一个表。这两个表没有任何关系。
这是虚拟示例设置
CREATE TABLE config (
idp INT NOT NULL,
eff_date DATE NOT NULL ,
last_transaction DATE NOT NULL,
a VARCHAR(50) NULL
);
INSERT INTO config (idp, eff_date, last_transaction, a)
VALUES
(1, DATE '2021-05-03', DATE '2021-05-02', 'abc')
;
CREATE TABLE transactions (
mth_eff_date DATE NOT NULL ,
amt INT NOT NULL
);
CREATE INDEX transaction_date ON transactions (mth_eff_date);
INSERT INTO transactions VALUES (DATE '2021-05-02', 825);
INSERT INTO transactions VALUES (DATE '2021-05-02', 650);
INSERT INTO transactions VALUES (DATE '2021-05-02', 825);
INSERT INTO transactions VALUES (DATE '2021-05-03', 500);
INSERT INTO transactions VALUES (DATE '2021-05-03', 650);
INSERT INTO transactions VALUES (DATE '2021-05-04', 235);
INSERT INTO transactions VALUES (DATE '2021-05-06', 853);
这是我的解决方案,它在大型数据集上的性能非常差。在测试时我检查了运行时间,如果我硬编码 (SELECT last_transaction from lt) 部分并且它运行得非常快。
WITH lt AS
(SELECT last_transaction
FROM config
),
transactions_filt AS
(SELECT *
FROM transactions
WHERE mth_eff_date <= (SELECT last_transaction FROM lt)
)
SELECT * FROM transactions_filt
;
(以上内容以fiddle的形式提供。)
最好的方法是什么?
【问题讨论】:
-
有点猜想,但如果你做了
select max(last_transaction) from lt,你可能会欺骗优化器进入使用一次性值而不是表值的计划。这可能会有所帮助,因为可能会删除 lt CTE -
STR_TO_DATE是 MySQL 函数,而不是 Oracle 数据库函数。请正确标记您的问题,因为您的查询的正确语法和预期的优化器行为可能会有所不同。 -
@LoztInSpace 不幸的是,这不起作用
-
请发布查询计划。
test.config.last_transaction上有索引吗?test.transactions.mth_eff_date上有索引吗? -
@wxecqz123 。 . .
insert代码仍然不兼容 Oracle,这使问题变得混乱。