我在本地计算机上构建了一个mysql表来存储股票市场数据。表名是minute_data
,结构很简单:
您可以看到我将键列设为日期和符号的组合 - > concat(date,symbol)
。这样我就可以进行insert ignore ...
查询,无需复制日期/符号组合即可向表中添加数据。
使用此表,数据检索非常简单。假设我想获得符号CSCO
的所有数据,那么我可以简单地执行此查询:
select * from minute_data where symbol = "CSCO" order by date;
一切都“有效”。该表现在包含超过1000个符号的数据,已经有超过2200万行。我认为对于所有1000个符号来说,甚至还不到半满,所以我希望不断增加表格的大小。
查询此表时,我开始看到严重的性能问题。例如,以下查询(我经常想要查看特定符号的最新日期)需要超过1分钟才能完成,并且只返回1行!
select * from minute_data where symbol = "CSCO" order by date desc limit 1;
此查询(也非常重要)平均花费超过1分钟:
select count(*), symbol from minute_data group by symbol;
性能问题使以这种方式继续处理数据变得不切实际。这些是我想问社区的问题:
继续在此表中构建数据集是徒劳的吗?
对于像这样的数据集,MySQL完全是一个糟糕的选择吗?
我可以对此表做些什么来提高性能?
我应该使用什么样的数据结构(而不是MySQL表)?
谢谢!
更新
我提供explain
的输出,以下两个查询相同:
explain select count(*), symbol from minute_data group by symbol;
explain select * from minute_data where symbol = "CSCO" order by date desc limit 1;
更新2
非常简单的修复。我执行了此查询以删除上面定义的无效key_col
,并在2列上创建了主键:日期和符号:
alter table minute_data drop primary key,添加主键(日期,符号);
现在我尝试了以下查询,并在不到1秒的时间内完成:
select * from minute_data where symbol = "CSCO" order by date desc limit 1;
此查询仍需要很长时间才能完成(72秒)。我想这仍然是因为查询必须在一个查询中列出所有2200万行?:
select count(*), symbol from minute_data group by symbol;
答案 0 :(得分:1)
你的key_col完全没用。您知道可以在多个列上拥有主键吗?我建议您删除该列并按此顺序在(日期,符号)上创建新的主键,因为您的日期列具有更高的基数。此外,您可以(如果需要)在(符号,日期)上创建另一个唯一索引。发布EXPLAIN
个最重要的查询。什么是symbol
的基数?
<强>更新强>
您在解释中可以看到,没有可以使用的索引,它扫描整个2250万行。请试试上面提到的。如果您不想立即删除key_col,则至少应在符号列上添加索引。