草庐IT

mysql - 快速用大量行填充 MySQL

coder 2023-10-02 原文

我有一个 MySQL 表,如下所示:

创建结构的 SQL 是:

CREATE TABLE `status` (
`id` INT(11) NOT NULL,
`responseCode` INT(3) NOT NULL DEFAULT '503',
`lastUpdate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

它存储了一个唯一的idresponseCodelastUpdateresponseCode 是 HTTP 请求响应代码:404、500、503、200 等。

我有一个 URL 对应于我发出 HTTP 请求的每个 id 并在此表中记录我发出请求和收到响应的时间。

脚本对 status 表进行查询:

SELECT id FROM status WHERE lastUpdate < 'XXXX' OR 
(responseCode != 200 AND responseCode != 404) 
ORDER BY id DESC LIMIT 100

XXXX 是一个日期,我决定无论响应代码如何,都需要刷新早于该日期的所有内容。此外,如果我没有收到 200404,无论上次 lastUpdate 日期如何,我都想重新尝试 HTTP 请求。我将 LIMIT 设置为 100,因为我一次只运行 100,然后我让它休眠一会儿,稍后再运行 100,依此类推。

无论如何,一切都很好,但我想做的是提前用这样的系列填充表格:

(1, 503, NOW()), (2, 503, NOW()), (3, 503, NOW()) ... (100000, 503, NOW())

注意,只有 ID 在递增,但根据我的需要,它不一定从 1 开始。我希望像这样预先填充表格,因为这样上面的查询可以继续为我们需要重新尝试的那些抓取 id,而且我不想再插入任何东西到status 表,因为 id 是有限的并且不会改变(但它们有很多)。

我尝试使用 JAVA,(虽然 PHP、C# 或其他任何东西都是相同的概念,对我来说我在这里使用哪种语言并不重要):

PreparedStatement st = conn.prepareStatement("INSERT INTO status VALUES (?,default,default)");

for( int i = 1; i <= 100000; i++ ) {
    st.setInt(1,i);
    st.addBatch();
}

System.out.println( "Running batch..." );
st.executeBatch();
System.out.println( "Batch done!" );

这将启动插入,但问题是填充表需要大量时间(我没有确切时间,但它运行了几个小时)。所以,我的问题归结为:是否有一种简单有效的方法来使用像这样的大量行填充 MySQL 表?

最佳答案

一般来说,您可以使用以下任何一项或多项:

  • 开始一个事务,做插入,提交
  • 将多个值打包到单个插入到查询中
  • 在执行插入之前删除任何约束并在批量插入之后恢复约束(除了可能的主键,虽然不是很确定)
  • 如果合适,使用insert into ... select

第一个(使用事务)最有可能有所帮助,但我不确定它是否适用于 myisam 表,使用 innodb 它做得很好 - 我只在被迫使用 mysql 时才使用它们,我更喜欢 postgresql。

在您的特定情况下,插入 100000 行数据,您可以执行以下操作:

INSERT INTO status(id, responseCode, lastUpdate) SELECT @row := @row + 1 as row, 503, NOW() FROM 
(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t5, 
(SELECT @row:=0) t6;

在我的机器上测试了这个,得到:

Query OK, 100000 rows affected (0.70 sec)
Records: 100000  Duplicates: 0  Warnings: 0

我敢肯定,对于 100000 行,您无法获得比这更快的速度。

关于mysql - 快速用大量行填充 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12788494/

有关mysql - 快速用大量行填充 MySQL的更多相关文章

  1. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  2. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  3. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置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

  4. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。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

  5. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用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

  6. ruby - 如何用递增的值填充数组 Ruby - 2

    我正在尝试解决http://projecteuler.net/problem=1.我想创建一个方法,它接受一个整数,然后创建一个包含它前面的所有整数的数组,并将整数本身作为数组中的值。以下是我目前所拥有的。代码不起作用。defmake_array(num)numbers=Array.newnumcount=1numbers.eachdo|number|numbers 最佳答案 (1..num).to_a是您在Ruby中需要做的全部。1..num将创建一个Range对象,以1开始并以任意值num结束是。Range对象有to_a方法通过

  7. ruby-on-rails - RoR中是否有任何内置方法可以为整数填充零? - 2

    如果我想要“00001”而不是“1”,除了我自己写填零方法之外,有没有内置的方法可以帮助我为整数填零? 最佳答案 puts"%05d"%1#00001参见:String::%,Kernel::sprintf这是正在发生的事情。%左侧的"%05d"是C风格的格式说明符。%右边的变量就是要格式化的东西。格式说明符可以像这样解码:%-格式说明符的开头0-用前导零填充5-长度为5个字符d-被格式化的是一个整数如果你要格式化多个东西,你会把它们放在一个数组中:"%d-%s"%[1,"One"]#=>1-one

  8. ruby - 如何以表格格式快速打印 Ruby 哈希值? - 2

    有没有办法快速将表格格式的ruby​​哈希打印到文件中?如:keyAkeyBkeyC...1232343451253474456...其中散列的值是不同大小的数组。还是使用双循环是唯一的方法?谢谢 最佳答案 试试我写的这个gem(在表中打印散列、ruby对象、ActiveRecord对象):http://github.com/arches/table_print 关于ruby-如何以表格格式快速打印Ruby哈希值?,我们在StackOverflow上找到一个类似的问题:

  9. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  10. ruby-on-rails - 用一系列时间增量填充选择,加上其他选项 - 2

    使用RubyonRails,我使用给定的增量(例如每30分钟)用时间填充“选择”。目前我正在YAML文件中写出所有的可能性,但我觉得有一种更巧妙的方法。我想我想提供一个开始时间、一个结束时间、一个增量,并且目前只提供一个名为“关闭”的选项(想想“business_hours”)。所以,我的选择可能会显示:'Closed'5:00am5:30am6:00am...[allthewayto]...11:30pm谁能想出更好的方法,或者只是将它们全部“拼写”出来的最佳方法? 最佳答案 此答案基于@emh的答案。defcreate_hour

随机推荐