mysql - mysql:如何更快地插入具有许多索引的表中?
问题描述
我有一个大约有 50 个索引的分区表,我每天将插入大约 2000 万条记录。
每次我打电话insert into tableA values (..),(..)...
插入 2000 条记录。这大约需要五个小时。我无法从文件中加载数据。所以我创建了一个talbeB
与 相同的表tableA
,但tableB
没有索引。首先我将数据插入到tableB
中,然后我调用insert into tableA select * from tableB where mydate = 20181119
. 第一阶段约40分钟,第二阶段约1小时。
我想知道是否有更快的方法。非常感谢!
解决方案
- 不要单独索引标志或其他低基数列。优化器不会使用索引。
UNIQUE
索引比非唯一索引更昂贵。你有多少。- 在单个
INSERT
语句中一次批处理 100 行,而不是 2000 行。 - 是否涉及复制?
- 表是 InnoDB 吗?(MyISAM 有很多其他问题,以及一些解决方案。)
- 你有多少内存?的价值是
innodb_buffer_pool_size
多少? - “第一阶段”是什么意思?
PARTITION
按日期?提供实际的分区定义。有好的方法和无用的方法。- 多少个分区?超过 50 个有性能问题。告诉我有多少,加上提供
SHOW VARIABLES
和SHOW GLOBAL STATUS
;如果你有太多可能有一个解决方法。 - 你会清除“旧”数据吗?这就是分区的原因吗?如果没有,那么分区可能弊大于利。
- 不要使用 RAM 盘;它消除了对 RAM 的更好使用。
- 要插入多少行,多久插入一次?也就是说,这是每小时加载 2M 行吗?还是250/秒的连续负载?还是其他模式?
- SSD驱动器?
- 这闻起来像一个数据仓库。有很多这样的技术。主要是将事实表中的内容卸载到汇总表中。执行此操作后,您可能可以摆脱 50 个索引中的大部分。此外,从摘要表构建“报告”的速度可能是直接从事实表构建“报告”的 10 倍。
请提供SHOW CREATE TABLE
进一步讨论。您可以混淆列名,但要与索引一致并具有实际的数据类型。
DW: 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
推荐阅读
- r - 如何使用 R 中的 dplyr 只保留那些一起包含最长连续运行的变量加一的行?
- flutter - 在颤动中传递选定索引的更好方法
- controller - G-code G1 移动指令与 MM114 获取电机位置指令不一致
- asp.net - 如何通过 VB.Net 中的 Drive API 将文件上传到 Google 共享驱动器?
- c# - 对从 ICollection 对象创建的 List<> 执行操作 - ICollection 对象正在更改
- javascript - 拖动链接的图像(不触发链接)
- c# - 在静态类定义中得到 SA1401
- excel - 返回最大日期的行号
- python - 使用numpy中另一个数组的值从一个数组中选择值
- javascript - Angular - 在另一个组件中使用由回调设置的服务属性