【发布时间】:2022-01-06 21:22:39
【问题描述】:
如何优化这个 SQLite 查询?目前运行需要 31 秒。我想在 Web 应用程序上显示前 10 名股票上涨者和前 10 名股票下跌者。该表有 200 万行,并且每天都有新的价格数据可用时会略微增加。
如果这不可能,我可以创建一个计划任务来将这些结果缓存到临时数据库表或临时文件中。看起来像是额外的工作,但如果需要也可以。
WITH todayPrices AS (
SELECT * FROM (
SELECT *, row_number() OVER (
PARTITION BY CompanyID
ORDER BY Date DESC
) AS rn
FROM DimCompanyPrice
) a
WHERE rn = 1
ORDER BY CompanyID ASC
),
yestPrices AS (
SELECT * FROM (
SELECT *, row_number() OVER (
PARTITION BY CompanyID
ORDER BY Date DESC
) AS rn
FROM DimCompanyPrice
) a
WHERE rn = 2
ORDER BY CompanyID ASC
)
SELECT todayPrices.CompanyID, 100.0 * (todayPrices.CloseAdjusted-yestPrices.CloseAdjusted) / yestPrices.CloseAdjusted AS gain
FROM todayPrices
INNER JOIN yestPrices on todayPrices.CompanyID=yestPrices.CompanyID
ORDER BY gain DESC
LIMIT 10
我想要一些关于什么是让它表现更好的最佳方法的意见。任何意见将不胜感激。
EXPLAIN QUERY PLAN的结果:
id parent notused detail
3 0 0 MATERIALIZE 2
5 3 0 CO-ROUTINE 1
8 5 0 CO-ROUTINE 6
11 8 0 SCAN TABLE DimCompanyPrice
36 8 0 USE TEMP B-TREE FOR ORDER BY
62 5 0 SCAN SUBQUERY 6
134 3 0 SCAN SUBQUERY 1 AS a
163 3 0 USE TEMP B-TREE FOR ORDER BY
174 0 0 MATERIALIZE 4
176 174 0 CO-ROUTINE 3
179 176 0 CO-ROUTINE 7
182 179 0 SCAN TABLE DimCompanyPrice
207 179 0 USE TEMP B-TREE FOR ORDER BY
233 176 0 SCAN SUBQUERY 7
305 174 0 SCAN SUBQUERY 3 AS a
334 174 0 USE TEMP B-TREE FOR ORDER BY
345 0 0 SCAN SUBQUERY 4
357 0 0 SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX (CompanyID=?)
382 0 0 USE TEMP B-TREE FOR ORDER BY
【问题讨论】:
-
并从 CTE 中删除
ORDER BYs。 -
有一个 CTE,其中 rn = 1 或 rn = 2,然后在最终 SELECT 中自行加入该 CTE
-
放弃
ORDER BY或使用单个CTE的建议都没有提高性能。 -
您需要使用为您需要帮助的 SQL 语句运行 EXPLAIN QUERY PLAN 的结果来更新您的问题。如果 SQL 语句不是您的问题中已经存在的语句(因为您已使用之前的建议之一对其进行了更新),那么请包含与 EXPLAIN QUERY PLAN 对应的 SQL 语句
标签: sql sqlite greatest-n-per-group window-functions conditional-aggregation