这里有一个关于如何正确配置 mysql (myisam) 以快速执行批量插入(加载数据 infile)的问题。
有 6 Gb 的文本文件要导入,1500 万行,16 列(一些 int,一些 varchar(255),一个 varchar(40),一个 char(1) 一些日期时间,一个 mediumtext)。
相对 my.conf 设置:
key_buffer = 800M
max_allowed_packet = 160M
thread_cache_size = 80
myisam_sort_buffer_size = 400M
bulk_insert_buffer_size = 400M
delay_key_write = ON
delayed_insert_limit = 10000
共有三个索引 - 一个主索引(autincrement int)、一个唯一的 int 和一个唯一的 varchar(40)。
问题是在执行 load data infile 命令后,前 3 gig 数据被快速导入(基于 table.myd 的增加大小 - 5-8 mb/s),但很快就超过了 3020 Mb 的限制导入速度大大降低 - table.myd 的大小正在增长 0.5mb/s。我注意到,当 Key_blocks_unused 耗尽为零时,导入过程会变慢。这些是导入开始时 mysql> show status like '%key%'; 的输出:
mysql> show status like '%key%';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| Com_preload_keys | 0 |
| Com_show_keys | 0 |
| Handler_read_key | 0 |
| Key_blocks_not_flushed | 57664 |
| Key_blocks_unused | 669364 |
| Key_blocks_used | 57672 |
| Key_read_requests | 7865321 |
| Key_reads | 57672 |
| Key_write_requests | 2170158 |
| Key_writes | 4 |
+------------------------+---------+
10 rows in set (0.00 sec)
这就是它在 3020Mb 限制之后的样子,即当 key_blocks_unused 降为零时,这就是批量插入过程变得非常慢的时候:
mysql> show status like '%key%';
+------------------------+-----------+
| Variable_name | Value |
+------------------------+-----------+
| Com_preload_keys | 0 |
| Com_show_keys | 0 |
| Handler_read_key | 0 |
| Key_blocks_not_flushed | 727031 |
| Key_blocks_unused | 0 |
| Key_blocks_used | 727036 |
| Key_read_requests | 171275179 |
| Key_reads | 1163091 |
| Key_write_requests | 41181024 |
| Key_writes | 436095 |
+------------------------+-----------+
10 rows in set (0.00 sec)
问题很明显,根据我的理解 - 索引存储在缓存中,但是一旦缓存填满,索引就会一个一个地写入磁盘,这很慢,因此所有过程都会变慢。如果我禁用基于 varchar(40) 列的唯一索引,因此所有索引都适合 Key_blocks_used(我猜这是直接依赖于 key_buffer 的变量,是'it?), 全部批量导入成功。所以,我很好奇,如何让mysql一次把所有Key_blocks_used数据放到磁盘,并释放Key_blocks_used?。我知道它可能会即时进行一些排序,但我仍然认为它应该可以进行一些缓存的 RAM 磁盘同步,以便成功管理索引,即使它们不适合内存缓存.所以我的问题是“如何配置 mysql,以便批量插入避免在(几乎)每个索引上写入磁盘,即使所有索引都不适合缓存?”最后一点 - delay_key_write对于给定的表设置为 1,但与禁用时相比,它没有增加任何加速。
提前感谢您的任何想法、想法、解释和 RTM! (:
还有一个小问题 - 在 Key_blocks_unused 变为 0 之前,我如何计算有多少 varchar(40) 索引适合缓存?
附言使用 $myisamchk --keys-used=0 -rq/path/to/db/tbl_name 禁用索引,然后使用 $myisamchk -rq/path/to/db/重新启用它们tbl_name,如 Mysql docs 中所述是一个已知的解决方案,它有效,但只有在批量插入到一个空表中时才有效。当表中已经有一些数据时,索引唯一性检查是必要的,因此禁用索引不是解决方案。
最佳答案
当您使用“load data infile”导入数据时,我认为 mysql 会一个接一个地执行插入,并且在每次插入时,它也会尝试更新索引文件 .MYI,这可能会减慢您的导入速度,因为它会消耗 bot每个单独插入的 I/O 和 CPU 资源。
您可以做的是将 4 个文件添加到您的导入文件以禁用表的键并在插入语句的末尾启用它,您应该会看到不同之处。
LOCK TABLES tableName WRITE;
ALTER TABLE tableName DISABLE KEYS;
----
your insert statement from go here..
----
ALTER TABLE tableName ENABLE KEYS
UNLOCK TABLES;
如果您不想编辑您的数据文件,请尝试使用 mysqldump 来获取正确的转储文件,并且您不应该在导入数据时遇到这种缓慢的情况。
##Dump the database
mysqldump databaseName > database.sql
##Import the database
mysql databaseName < database.sql
希望这对您有所帮助!
关于mysql - 当索引不适合 key_buffer 时快速 MySQL 批量加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1693614/
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我发现自己需要这个。假设cart是一个包含用户列表的模型。defindex_of_itemcart.users.each_with_indexdo|u,i|ifu==current_userreturniendend获取此类关联索引的更简单方法是什么? 最佳答案 indexArray上的方法与您的index_of_item方法相同,例如cart.users.index(current_user)返回数组中第一个对象的索引==给obj。如果未找到匹配项,则返回nil。 关于ruby-on-
因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi