使用mysql处理非常大的数据
抱歉发了这么长的帖子 我有一个包含30个表的数据库(InnoDB引擎)。其中只有两个表,即“transaction”和“shift”相当大(第一个表有150万行,而shift有23k行)。现在一切正常,我对当前的数据库大小没有问题 然而,我们将有一个类似的数据库(相同的数据类型、设计等等),但要大得多,例如,“事务”表将有大约10亿条记录(每天大约230万个事务),我们正在考虑如何在MySQL中处理如此大的数据量?(它是读写密集型)。我读了很多相关的帖子,想看看Mysql(更具体地说是InnoDB引擎)能否在数十亿条记录上表现良好,但我仍然有一些问题。我读过的一些相关帖子如下:使用mysql处理非常大的数据,mysql,database,performance,indexing,partitioning,Mysql,Database,Performance,Indexing,Partitioning,抱歉发了这么长的帖子 我有一个包含30个表的数据库(InnoDB引擎)。其中只有两个表,即“transaction”和“shift”相当大(第一个表有150万行,而shift有23k行)。现在一切正常,我对当前的数据库大小没有问题 然而,我们将有一个类似的数据库(相同的数据类型、设计等等),但要大得多,例如,“事务”表将有大约10亿条记录(每天大约230万个事务),我们正在考虑如何在MySQL中处理如此大的数据量?(它是读写密集型)。我读了很多相关的帖子,想看看Mysql(更具体地说是InnoD
innoDB_buffer_pool_size
(例如,高达RAM的80%)。
此外,我还发现了一些其他MySQL性能调优设置- 关于分区,我怀疑我们是否应该使用它。一方面,很多人建议在桌子很大的时候提高性能。另一方面,我读过很多帖子,说它不能提高查询性能,也不能使查询运行得更快(例如,和)。此外,我还了解到InnoDB外键和MySQL分区不兼容(我们有外键)
- 关于索引,目前它们的性能很好,但据我所知,对于非常大的表,索引更具限制性(正如Kevin Bedell在回答中提到的)。此外,索引加快了读取速度,同时降低了写入速度(插入/更新)。因此,对于新的类似项目,我们将有这么大的数据库,我们应该首先插入/加载所有数据,然后创建索引吗?(以加快插入速度)
- 如果我们不能对我们的大表(“事务”表)使用分区,那么有什么替代选项可以提高性能?(MySQl变量设置除外,如
)。我们应该使用Mysql集群吗?(我们也有很多加入)innodb\u buffer\u pool\u size
show create table
语句:
谢谢您的时间,- MySQL能够合理地对数十亿行执行查询吗?--MySQL可以“处理”数十亿行。“合理”取决于询问;让我们看看
- InnoDB(MySQL 5.5.8)是数十亿行的正确选择吗5.7有一些改进,但5.5相当不错,尽管它已经将近6.8岁了,并且处于不再受支持的边缘
- 数十亿行的最佳数据存储——如果您指的是“引擎”,那么是InnoDB
- 在性能开始下降之前,MySQL数据库能有多大?同样,这取决于查询。我可以给你看一张1K行的桌子,它会崩溃;我曾经处理过数十亿行的表格
- 为什么MySQL在处理大型表时速度较慢?--范围扫描导致I/O,这是缓慢的部分
- Mysql能处理大约3亿条记录的表吗再一次,是的。限制大约在一万亿行左右
- (对于我的案例中的innoDB表)增加innoDB_buffer_pool_大小(例如,高达RAM的80%)。另外,我在percona博客中发现了其他一些MySQL性能调优设置——是的
- 在表上有适当的索引(在查询上使用EXPLAN)——好吧,让我们看看它们。在这一关键领域可能会犯很多错误
- 对表进行分区--“分区不是万能的!”我在
- MySQL分片——目前这是DIY
- MySQL集群——目前最好的答案是一些基于Galera的选项(PXC、MariaDB 10、DIY w/Oracle)。Oracle的“组复制”是一个可行的竞争者
- 分区不支持
或“全局”外键
唯一
- UUID,在您所说的规模上,不仅会减慢系统的速度,而且实际上会杀死它。这可能是一个解决办法
- 插入和索引构建速度--有太多的变体,无法给出单个答案。让我们看看您的暂定
创建表
,以及您打算如何输入数据
- 大量的连接--“规范化,但不要过度规范化”。特别是,不要规范化日期时间、浮点数或其他“连续”值
- 建造
- 每天230万个事务——如果这是230万次插入(30秒),那么性能问题就不大了。如果更复杂,则可能需要RAID、SSD、批处理等
- 处理如此大量的数据——如果大多数活动都是“最近”的行,那么缓冲池将很好地“缓存”活动,从而避免I/O。如果活动是“随机”的,那么MySQL(或其他任何人)将有I/O问题
- 在像您这样的表中,缩小数据类型很有帮助。我怀疑您是否需要4个字节来指定
。有多种1字节方法燃油类型
CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`terminal_transaction_id` int(11) NOT NULL,
`fuel_terminal_id` int(11) NOT NULL,
`fuel_terminal_serial` int(11) NOT NULL,
`xboard_id` int(11) NOT NULL,
`gas_station_id` int(11) NOT NULL,
`operator_id` text NOT NULL,
`shift_id` int(11) NOT NULL,
`xboard_total_counter` int(11) NOT NULL,
`fuel_type` int(11) NOT NULL,
`start_fuel_time` int(11) NOT NULL,
`end_fuel_time` int(11) DEFAULT NULL,
`preset_amount` int(11) NOT NULL,
`actual_amount` int(11) DEFAULT NULL,
`fuel_cost` int(11) DEFAULT NULL,
`payment_cost` int(11) DEFAULT NULL,
`purchase_type` int(11) NOT NULL,
`payment_ref_id` text,
`unit_fuel_price` int(11) NOT NULL,
`fuel_status_id` int(11) DEFAULT NULL,
`fuel_mode_id` int(11) NOT NULL,
`payment_result` int(11) NOT NULL,
`card_pan` text,
`state` int(11) DEFAULT NULL,
`totalizer` int(11) NOT NULL DEFAULT '0',
`shift_start_time` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `terminal_transaction_id` (`terminal_transaction_id`,`fuel_terminal_id`,`start_fuel_time`) USING BTREE,
KEY `start_fuel_time_idx` (`start_fuel_time`),
KEY `fuel_terminal_idx` (`fuel_terminal_id`),
KEY `xboard_idx` (`xboard_id`),
KEY `gas_station_id` (`gas_station_id`) USING BTREE,
KEY `purchase_type` (`purchase_type`) USING BTREE,
KEY `shift_start_time` (`shift_start_time`) USING BTREE,
KEY `fuel_type` (`fuel_type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1665335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT