我希望从一个名为price 的表中做一个相对简单的过滤器。
价格是一个非常大的表(~2G 记录)。下面包含示例数据、查询和索引。我意识到被查询的表非常大,但对于如此简单的查询,我期望有更好的性能(目前大约 5 分钟并正在运行)。我确实注意到每个 MySQL Workbench 的 InnoDB 缓冲区使用率似乎为 100%,每秒读取约 6K InnoDB。有关为纠正此问题而进行的调整的指导。
价格
dataDate ticker optionSymbol expDate type price strike last bid ask volume OI
2002-02-08 AAPL AAQ020216C00005000 2002-02-16 call 24.03 5 0 18.8 19.1 0 0
2002-02-08 AAPL AAQ020216P00005000 2002-02-16 put 24.03 5 0 0 0.05 0 0
2002-02-08 AAPL AAQ020216C00007500 2002-02-16 call 24.03 7.5 0 16.3 16.6 0 0
2002-02-08 AAPL AAQ020216P00007500 2002-02-16 put 24.03 7.5 0 0 0.05 0 0
2002-02-08 AAPL AAQ020216C00010000 2002-02-16 call 24.03 10 12.2 13.9 14.2 0 1
2002-02-08 AAPL AAQ020216P00010000 2002-02-16 put 24.03 10 0 0 0.05 0 0
2002-02-08 AAPL AAQ020216C00012500 2002-02-16 call 24.03 12.5 13.5 11.4 11.7 0 8
2002-02-08 AAPL AAQ020216P00012500 2002-02-16 put 24.03 12.5 0.05 0 0.05 0 50
2002-02-08 AAPL AAQ020216C00015000 2002-02-16 call 24.03 15 7.1 8.9 9.1 0 10
2002-02-08 AAPL AAQ020216P00015000 2002-02-16 put 24.03 15 0.1 0 0.05 0 30
2002-02-08 AAPL AAQ020216C00017500 2002-02-16 call 24.03 17.5 5.5 6.4 6.7 0 371
2002-02-08 AAPL AAQ020216P00017500 2002-02-16 put 24.03 17.5 0.05 0 0.05 0 147
2002-02-08 AAPL AAQ020216C00020000 2002-02-16 call 24.03 20 3.9 3.9 4.1 7 1064
2002-02-08 AAPL AAQ020216P00020000 2002-02-16 put 24.03 20 0.1 0 0.1 5 1448
2002-02-08 AAPL AAQ020216C00022500 2002-02-16 call 24.03 22.5 1.7 1.7 1.75 1551 7069
2002-02-08 AAPL AAQ020216P00022500 2002-02-16 put 24.03 22.5 0.2 0.15 0.25 136 3234
2002-02-08 AAPL AAQ020216C00025000 2002-02-16 call 24.03 25 0.3 0.1 0.35 105 4237
2002-02-08 AAPL AAQ020216P00025000 2002-02-16 put 24.03 25 1.25 1.2 1.35 629 589
2002-02-08 AAPL AAQ020216C00027500 2002-02-16 call 24.03 27.5 0.05 0 0.1 0 1097
Run Code Online (Sandbox Code Playgroud)
询问
select *
from op.prices op
where ticker = 'AAPL'
and '2020-04-30' between date_add(expDate, INTERVAL 3 MONTH) and expDate
and '2020-04-30' = date_add(op.dataDate, INTERVAL 14 DAY);
Run Code Online (Sandbox Code Playgroud)
bba*_*ird 33
代替
'2020-04-30' = date_add(op.dataDate, INTERVAL 14 DAY);
Run Code Online (Sandbox Code Playgroud)
用
op.dataDate = date_sub('2020-04-30', INTERVAL 14 DAY);
Run Code Online (Sandbox Code Playgroud)
您的第一条语句将被解释为“将所有天数添加 14 天dataDate并在 2020 年 4月 30 日返回。” 这将需要对表进行全面扫描。
第二个语句将评估为:“返回dataDate2020-04-16 的记录。” 这允许引擎对以 开头的索引执行搜索dataDate。
做任何你想做的奇怪的事情,expDate因为这不会影响查询引擎将如何优化。
配方是主要问题。重写查询后,您拥有的索引可以用于整个WHERE子句。
SELECT *
FROM op.prices
WHERE ticker = 'AAPL'
AND expDate >= '2020-04-30'
AND expDate < '2020-04-30' + INTERVAL 3 MONTH
AND dataDate = '2020-04-30' - INTERVAL 14 DAY
Run Code Online (Sandbox Code Playgroud)
请参阅维基百科中的 Sargeable。换种说法“不要在函数调用中隐藏列——它可能无法被索引使用。”
缩小文件大小会有所帮助:
DOUBLE(大约 16 位有效数字)切换到 4 字节FLOAT(大约 7 位有效数字)。ENUM('put','call')将每行节省 3 个字节。可能还有更多提示。要了解缩小的重要性,请回答以下问题:您有多少 RAM?的价值是innodb_buffer_pool_size什么?表有多大(GB)?
你真的应该有一个PRIMARY KEY.
| 归档时间: |
|
| 查看次数: |
2851 次 |
| 最近记录: |