我有一个大约有50个索引的分区表,每天我将插入大约2000万条记录。
每次我打电话 insert into tableA values (..),(..)...
插入2000条记录。这大约需要5个小时。我无法从文件加载数据。所以我创建了一个表 talbeB
和…一样 tableA
,但是 tableB
没有索引。首先我将数据插入 tableB
,然后我打电话 insert into tableA select * from tableB where mydate = 20181119
. 第一阶段约40分钟,第二阶段约1小时。
我想知道有没有更快的方法。谢谢!
1条答案
按热度按时间5us2dqdw1#
不要单独索引标志或其他低基数列。优化器不会使用索引。
UNIQUE
索引比非唯一索引成本更高。你有多少个。批处理100,而不是一次处理2000行
INSERT
声明。是否涉及复制?
table是innodb吗(myisam还有很多其他问题,还有一些解决方案。)
你有多少公羊?它的价值是什么
innodb_buffer_pool_size
?你说的“第一阶段”是什么意思?
PARTITION
按日期?提供实际的分区定义。有好的方法,也有无用的方法。有多少个分区?超过50个有性能问题。告诉我有多少,再加上
SHOW VARIABLES
以及SHOW GLOBAL STATUS
; 如果你有太多的话,可能会有一个解决办法。你会清除“旧”数据吗?这就是分区的原因吗?如果不是这样的话,那么分割可能是弊大于利。
不要使用ram磁盘;它减少了ram的更好使用。
要插入多少行,插入的频率是多少?也就是说,这是每小时200万行的负载吗?或者是250次/秒的连续负载?或者其他模式?
ssd驱动器?
这闻起来像个数据仓库。有很多方法可以解决这个问题。主要的方法是将事实表中的内容卸载到摘要表中。一旦你这么做了,你也许可以去掉50个索引中的大部分。此外,从摘要表构建“报告”的速度可能是直接从事实表构建“报告”的速度的10倍。
请提供
SHOW CREATE TABLE
供进一步讨论。您可以混淆列名,但要与索引一致,并具有实际的数据类型。数据仓库:http://mysql.rjweb.org/doc.php/datawarehouse
汇总表:http://mysql.rjweb.org/doc.php/summarytables
高速摄入(以“连续”为目标):http://mysql.rjweb.org/doc.php/staging_table
分区:http://mysql.rjweb.org/doc.php/partitionmaint