Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.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_Sql - Fatal编程技术网

重复密钥更新时有数百万MySQL插入-速度非常慢

重复密钥更新时有数百万MySQL插入-速度非常慢,mysql,sql,Mysql,Sql,我有一个名为research\u words的表,它有大约一亿行 每天我要添加数千万行新行,其中大约5%是全新的行,95%是更新,必须添加到该行的某些列中。我不知道哪个是哪个,所以我使用: INSERT INTO research_words (word1,word2,origyear,cat,numbooks,numpages,numwords) VALUES (34272,268706,1914,1,1,1,1) ON DUPLICATE KEY UPDATE numbooks=

我有一个名为
research\u words
的表,它有大约一亿行

每天我要添加数千万行新行,其中大约5%是全新的行,95%是更新,必须添加到该行的某些列中。我不知道哪个是哪个,所以我使用:

INSERT INTO research_words
  (word1,word2,origyear,cat,numbooks,numpages,numwords)
VALUES
  (34272,268706,1914,1,1,1,1)
ON DUPLICATE KEY UPDATE
  numbooks=numbooks+1,numpages=numpages+1,numwords=numwords+1
这是一个InnoDB表,其中主键位于
word1、word2、origyear、cat
上方

我遇到的问题是,我必须每天插入新行,而每天插入新行所需的时间超过24小时!显然,我不能让插入当天行的时间超过一天。我得想办法让插页更快

对于其他表,我在
altertable中取得了巨大成功。。。禁用密钥
加载数据填充
,这使我可以在不到一小时的时间内添加数十亿行。那太好了,但不幸的是,我正在增加这个表中的列。我怀疑禁用这些键是否会有帮助,因为肯定需要它们检查行是否存在才能添加它

我的脚本是用PHP编写的,但当我添加行时,我会通过一个
exec
调用直接向MySQL传递一个命令文本文件,而不是用PHP发送,因为这样做速度更快


有没有解决速度问题的办法?

这是一个老问题,但还是值得一提。 问题的部分原因在于大量插入操作一次只运行一个,每次插入后都会有一个唯一的索引更新。
在这些情况下,更好的方法可能是选择要插入的n行并将它们放入临时表中,将它们左键连接到目标表,计算它们的新值(在OP的情况下为IFNULL(dest.numpages+1,1)等),然后运行另外两个命令—插入字段为1的insert命令和插入字段较大的update命令。更新不需要索引刷新,因此运行速度更快;插入不需要相同的复制键逻辑。

很抱歉出现offtop,但有趣的是,使用direct exec命令可以获得多少好处?你测量过了吗?MySQL只是将它作为一个巨大的查询来处理,而不是数百万个单独的查询,特别是在禁用了键的情况下,它的处理效率更高。区别是几分钟而不是几小时。这就是我所理解的,但是您可以使用PDO或mysqli适配器发送大型查询,而不是通过exec命令与MySQL交互。这样做的好处是什么?是的,当然可以,速度也差不多,我提到的性能提升是假设单个查询(这将是低效的)。在我的例子中,我正在导入几GB大小的文件——通过PHP将其发送到MySQL是不可行的。将所有内容保存到一个文件中,然后使用MySQL更直接地导入该文件更有意义。ALTER TABLE DISABLE KEYS仅禁用非唯一键,因此,如果除了用于检查行是否存在的唯一键之外,还具有非唯一键,则可以将其添加到插入中。但是,我怀疑它是否能将插入时间减少到24小时阈值以下。资料来源: