MySQL table 设置股票信息
MySQL table setup for stock information
我每天收集大约 3 - 6 百万行股票数据并将其存储在 MySQL 数据库中。
所有数据均来自盈透证券,每条信息都带有这五个字段:符号、日期、时间、值和类型(类型是关于我收到的数据类型的信息,例如价格、交易量等等)
这是我的创建 table 语句。 idticks 只是我的唯一键,但我几乎无法在查询中使用它。
CREATE TABLE `ticks` (
`idticks` int(11) NOT NULL AUTO_INCREMENT,
`symbol` varchar(30) NOT NULL,
`date` int(11) NOT NULL,
`time` int(11) NOT NULL,
`value` double NOT NULL,
`type` double NOT NULL,
KEY `idticks` (`idticks`),
KEY `symbol` (`symbol`),
KEY `date` (`date`),
KEY `idx_ticks_symbol_date` (`symbol`,`date`),
KEY `idx_ticks_type` (`type`),
KEY `idx_ticks_date_type` (`date`,`type`),
KEY `idx_ticks_date_symbol_type` (`date`,`symbol`,`type`),
KEY `idx_ticks_symbol_date_time_type` (`symbol`,`date`,`time`,`type`)
) ENGINE=InnoDB AUTO_INCREMENT=13533258 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY (`date`)
PARTITIONS 1 */;
如您所见,我不知道自己在做什么,因为我一直在创建索引以使查询速度更快。
目前,出于测试目的,数据存储在一台相当慢的计算机上,所以我知道我的查询速度并没有达到预期的速度(我有一台 6 核、64g 内存、SSD 机器明天到货这应该有很大帮助)
话虽这么说,我 运行 这样的查询
select time, value from ticks where symbol = "AAPL" AND date = 20150522 and type = 8 order by time asc
上面的查询,如果我不限制它,returns 我的测试日中有 12928 条记录,如果我从清除缓存中执行它需要 10.2 秒。
我正在做很多图表,最终希望能够在我需要图表时查询数据。现在我还没有注意到获取一天的部分数据与只获取一整天的数据在速度上有很大差异。如果这些查询的响应速度足够快,以至于当我转到下一个 day/screen 时几乎没有任何延迟,那就太好了。
我正在使用的另一个查询,用于了解我正在编写的与数据交互的程序的可用性,包括
String query = "select distinct `date` from ticks where symbol = '" + symbol + "' order by `date` desc";
但我最需要的是能够像我的第一个查询那样从某一天为某个符号提取某种类型的数据。
我到处搜索,我想我明白创建大量索引会使数据库变大并减慢输入速度(在忙碌的一天我每秒获得大约 300 条信息)。我应该单独为每一列编制索引吗?
如果这意味着响应式界面,我愿意投入更多硬盘。
基本上,我的问题与 table 的 creation/altering 有关。基于上面的查询,你能想到我可以做些什么来让它更快吗?或者可以帮助我的索引系统? InnoDB 是正确的引擎吗?我试着用谷歌搜索这个和 MyISam,几个小时后,我仍然不确定。
谢谢:)
您正在创建一个历史数据库,因此 MyISAM 可以像 InnoDB 一样工作。 InnoDB 是一个事务型关系数据库,更适合具有多个 table 且必须保持同步的关系数据库。
您的库存 table 看起来像这样。
Stock
-----
Stock ID (idticks)
Symbol
Date
Time
Value
Type
如果将日期和时间合并成一个时间戳列,然后像这样解压类型就更好了。
Stock
-----
Stock ID
Symbol
Time Stamp
Volume
Open
Close
Bid
Ask
...
这使得数据库更容易 return 行查询特定类型,例如收盘值。
至于索引,您可以创建任意数量的索引。您正在添加(插入)信息,因此添加信息的时间增加会被查询信息的时间减少所抵消。
我有一个关于股票 ID 的主索引,以及一个关于符号和时间戳降序的唯一索引。您还可以为最常查询的值创建索引,例如 Close。
- 将日期和时间合并到 DATETIME 字段中
- 假设价格和成交量总是在一起,将它们放在一起(2 列)并在
type
时去掉。
- 去掉
AUTO_INCREMENT
;更改为 PRIMARY KEY(symbol, datetime)
- 删除其他索引左侧的任何索引。
- 使用 DATETIME 后,使用日期范围查找单个日期中的所有内容(如果需要)。 不要使用
DATE(datetime) = '...'
,性能会很糟糕。
Symbol
可能是 ascii,不是 utf8。
- 使用 InnoDB,主键的集群可能是有益的。
- 您是否希望收集(和使用)比
innodb_buffer_pool_size
容纳的更多的数据?如果是这样,我们需要讨论您的 SELECTs
并调查 PARTITIONing
.
进行这些更改,然后回来进行更多更改 advice/abuse。
我每天收集大约 3 - 6 百万行股票数据并将其存储在 MySQL 数据库中。
所有数据均来自盈透证券,每条信息都带有这五个字段:符号、日期、时间、值和类型(类型是关于我收到的数据类型的信息,例如价格、交易量等等)
这是我的创建 table 语句。 idticks 只是我的唯一键,但我几乎无法在查询中使用它。
CREATE TABLE `ticks` (
`idticks` int(11) NOT NULL AUTO_INCREMENT,
`symbol` varchar(30) NOT NULL,
`date` int(11) NOT NULL,
`time` int(11) NOT NULL,
`value` double NOT NULL,
`type` double NOT NULL,
KEY `idticks` (`idticks`),
KEY `symbol` (`symbol`),
KEY `date` (`date`),
KEY `idx_ticks_symbol_date` (`symbol`,`date`),
KEY `idx_ticks_type` (`type`),
KEY `idx_ticks_date_type` (`date`,`type`),
KEY `idx_ticks_date_symbol_type` (`date`,`symbol`,`type`),
KEY `idx_ticks_symbol_date_time_type` (`symbol`,`date`,`time`,`type`)
) ENGINE=InnoDB AUTO_INCREMENT=13533258 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY (`date`)
PARTITIONS 1 */;
如您所见,我不知道自己在做什么,因为我一直在创建索引以使查询速度更快。
目前,出于测试目的,数据存储在一台相当慢的计算机上,所以我知道我的查询速度并没有达到预期的速度(我有一台 6 核、64g 内存、SSD 机器明天到货这应该有很大帮助)
话虽这么说,我 运行 这样的查询
select time, value from ticks where symbol = "AAPL" AND date = 20150522 and type = 8 order by time asc
上面的查询,如果我不限制它,returns 我的测试日中有 12928 条记录,如果我从清除缓存中执行它需要 10.2 秒。
我正在做很多图表,最终希望能够在我需要图表时查询数据。现在我还没有注意到获取一天的部分数据与只获取一整天的数据在速度上有很大差异。如果这些查询的响应速度足够快,以至于当我转到下一个 day/screen 时几乎没有任何延迟,那就太好了。
我正在使用的另一个查询,用于了解我正在编写的与数据交互的程序的可用性,包括
String query = "select distinct `date` from ticks where symbol = '" + symbol + "' order by `date` desc";
但我最需要的是能够像我的第一个查询那样从某一天为某个符号提取某种类型的数据。
我到处搜索,我想我明白创建大量索引会使数据库变大并减慢输入速度(在忙碌的一天我每秒获得大约 300 条信息)。我应该单独为每一列编制索引吗?
如果这意味着响应式界面,我愿意投入更多硬盘。
基本上,我的问题与 table 的 creation/altering 有关。基于上面的查询,你能想到我可以做些什么来让它更快吗?或者可以帮助我的索引系统? InnoDB 是正确的引擎吗?我试着用谷歌搜索这个和 MyISam,几个小时后,我仍然不确定。
谢谢:)
您正在创建一个历史数据库,因此 MyISAM 可以像 InnoDB 一样工作。 InnoDB 是一个事务型关系数据库,更适合具有多个 table 且必须保持同步的关系数据库。
您的库存 table 看起来像这样。
Stock
-----
Stock ID (idticks)
Symbol
Date
Time
Value
Type
如果将日期和时间合并成一个时间戳列,然后像这样解压类型就更好了。
Stock
-----
Stock ID
Symbol
Time Stamp
Volume
Open
Close
Bid
Ask
...
这使得数据库更容易 return 行查询特定类型,例如收盘值。
至于索引,您可以创建任意数量的索引。您正在添加(插入)信息,因此添加信息的时间增加会被查询信息的时间减少所抵消。
我有一个关于股票 ID 的主索引,以及一个关于符号和时间戳降序的唯一索引。您还可以为最常查询的值创建索引,例如 Close。
- 将日期和时间合并到 DATETIME 字段中
- 假设价格和成交量总是在一起,将它们放在一起(2 列)并在
type
时去掉。 - 去掉
AUTO_INCREMENT
;更改为PRIMARY KEY(symbol, datetime)
- 删除其他索引左侧的任何索引。
- 使用 DATETIME 后,使用日期范围查找单个日期中的所有内容(如果需要)。 不要使用
DATE(datetime) = '...'
,性能会很糟糕。 Symbol
可能是 ascii,不是 utf8。- 使用 InnoDB,主键的集群可能是有益的。
- 您是否希望收集(和使用)比
innodb_buffer_pool_size
容纳的更多的数据?如果是这样,我们需要讨论您的SELECTs
并调查PARTITIONing
.
进行这些更改,然后回来进行更多更改 advice/abuse。