Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
特定MySQL批量插入性能调整_Mysql_Database_Linux_Insert_Performance - Fatal编程技术网

特定MySQL批量插入性能调整

特定MySQL批量插入性能调整,mysql,database,linux,insert,performance,Mysql,Database,Linux,Insert,Performance,我知道这个问题已经被反复问过了。然而,对于一个非常具体的场景,这是一个非常具体的问题。希望你能帮助我 我运行一个日志数据库,大约有10个表。存储实际日志条目的主表有大约30个字段,其中5个可搜索。我要说的是,数据库最近变得中等规模,因为我们在该表中的条目达到了2亿个。其他表存储公共数据,其中最大的表有4个字段,所有字段都可搜索,有近100万个条目。所有其他表中每个表包含的记录都少于10万条 插入物有尖刺。我每天凌晨2点从csv文件中获取前一天的日志(格式非常糟糕),直到早上8点,我都要将它们(大

我知道这个问题已经被反复问过了。然而,对于一个非常具体的场景,这是一个非常具体的问题。希望你能帮助我

我运行一个日志数据库,大约有10个表。存储实际日志条目的主表有大约30个字段,其中5个可搜索。我要说的是,数据库最近变得中等规模,因为我们在该表中的条目达到了2亿个。其他表存储公共数据,其中最大的表有4个字段,所有字段都可搜索,有近100万个条目。所有其他表中每个表包含的记录都少于10万条

插入物有尖刺。我每天凌晨2点从csv文件中获取前一天的日志(格式非常糟糕),直到早上8点,我都要将它们(大约20个文件,每个10万行)插入数据库。然后我在工作日得到很少的选择(也许每天1000个左右)。然后冲洗并重复

SELECT查询非常简单,因为它们主要由一个或两个连接以及一个或两个GROUPBY语句组成。搜索此数据库的人希望立即得到结果,因此我在主表中有5个多列索引,这有助于我进行精确搜索,目前,SELECT性能相当好。到目前为止,没有任何查询花费的时间超过0.1秒。有一些报告,但生成这些报告大约需要10秒,这是可以接受的

目前,我编写了一个C程序,用于从CSV文件读取数据,清理数据,并在每次插入查询中批量插入1000行数据。这些插入并不完全是愚蠢的,因为我需要获取公共数据,查看它是否已经存在于其他表中,如果不存在则插入,如果存在则缓存。它还以每秒插入多少条记录的形式提供性能数据。这个程序相当快,并且不将数据发送到数据库,我每秒得到大约100000行。当然,这个程序和数据库位于同一台物理计算机上

现在,我每天得到的数据是线性增长的,插入的性能是对数下降的。昨天的数据需要5个半小时才能插入,大约每秒插入400行

我通过将具有不同配置的前100万行插入到一个空数据库中获得了一些基准数据,这就是我得到的:

MyISAM表格:从每秒1500行开始,在插入第一百万行时,以对数方式降低到每秒700行左右 InnoDB表:与MyISAM相同,每秒仅快100行左右 在主表上禁用所有索引的InnoDB:从每秒2100行开始,降低到每秒1000行。 带索引的InnoDB,安装了带数据写回(ext3)的文件系统:与InnoDB相同,只是稍微快一点,但几乎没有明显的速度

innodb_缓冲区_池_大小设置为1000MB

避免创建索引不是一种选择,但显然它对性能有很大影响。但是,我需要更快的插入。如数据所示,随着数据库的增长,插入将花费更长的时间,因此,随着我每天获得的数据越来越大,我需要在插入性能上有一个巨大的飞跃。如果我能让它每秒插入10000个或更多,那就太棒了

系统监视器告诉我,我的主要资源消耗是磁盘I/O,插入磁盘时几乎消耗100%。因此,我需要一种超快速的方法来插入数据。我的理论极限是SATA总线的极限,但这还很遥远。内存使用率在20%左右似乎没有那么高(或者MySQL没有正确使用内存)

为了实现这一点,可以在几天内重新创建数据库,然后从读卡器应用程序进行热交换,可以更改操作系统和MySQL中的任何设置,可以在需要时添加内存。如果需要,甚至可以更改数据库结构

所以我对这里的想法非常开放。有人知道有什么能帮我的吗


编辑:我目前正在考虑在内存表中插入新行,然后在实际表中进行选择。希望它只在插入所有行后更新和刷新索引一次。我星期一试试这个。以前有人尝试过类似的方法吗?

当提到磁盘I/O时,你会大吃一惊。如果你的磁盘插入量过大,除非你升级,否则你的速度不会更快。您没有提到磁盘升级是否可以接受,但我会考虑使用SCSI或基于闪存的磁盘。即使您没有达到SATA的总线限制,您的磁盘也绝对是瓶颈。

6.5小时内有200万行?
您存储的数据集有多大

我使用以下信封背面的计算得出一个有用的数字:
假设
1
一个每秒占用
35
mb的蹩脚磁盘,您应该能够在该时间段内写入(35*6,5*3600)=~
800 gb
。向后计算(800 gb/2 mrows),得到的平均行大小为
400
kb

如果这些数字似乎是正确的,您需要增强硬件以提高速度。如果它们完全关闭,则可能存在其他问题

另外,请查看服务器故障,了解测量I/O的方法

以下是一些随机建议(以防您怀疑其他问题)

  • 确保在加载过程中消除所有的逐行操作
  • 如果大部分CSV数据最终被存储,考虑到中间表并使用基于集合的处理来处理数据库内的数据。
  • 如果大部分数据被丢弃,请考虑移动/缓存数据库之外的引用表,以便能够过滤C代码
  • 中的CSV数据。
  • MySQL没有散列连接,但依赖于索引循环。确保其他人