编写快速 MySQL INSERT 查询或优化此查询

Posted

技术标签:

【中文标题】编写快速 MySQL INSERT 查询或优化此查询【英文标题】:Writing a fast MySQL INSERT query or optimization this query 【发布时间】:2016-04-10 08:29:23 【问题描述】:

我写了一个 INSERT 查询。在本地服务器上运行时,没有问题,但在实时服务器上运行相同的查询时会显示错误。

labtestdat 上的总数据 --> 51439

testmedical 上的总数据 --> 1684


本地服务器

插入查询:

INSERT INTO labtestdata(labid,testid) SELECT '131',id FROM testmedical 
WHERE id NOT IN(SELECT testid FROM labtestdata WHERE labid = '131') 

确认信息:

已插入 1684 行。 插入的行 id:67592(查询耗时 0.0318 秒。)

COUNT 个查询:

SELECT count(id) FROM testmedical WHERE id NOT IN(select testid FROM labtestdata WHERE labid = '131')

确认信息:

您的 SQL 查询已成功执行。

计数(id) 0


实时服务器

插入查询:

INSERT INTO labtestdata(labid,testid) SELECT '131',id FROM testmedical WHERE id NOT IN(SELECT testid FROM labtestdata WHERE labid = '131') 

确认信息:

#2013 - 查询期间与 mysql 服务器的连接丢失

COUNT 个查询:

SELECT count(id) FROM testmedical WHERE id NOT IN(select testid FROM labtestdata WHERE labid = '131')

确认信息(20秒后显示):

#2013 - 查询期间与 MySQL 服务器的连接丢失


注意:查询是使用 phpMyAdmin 运行的

如何解决这个问题?

【问题讨论】:

询问您的服务器管理员。这可能是因为net_read_timeout 服务器变量。通常默认为 30 秒。 但这不是解决方案,现在服务器上只有 50000+ 行,未来行 1000000+ ,,, 如何解决这个问题,请告诉我... 【参考方案1】:

构造NOT IN ( SELECT ... ) 性能不佳。将其转换为NOT EXISTS ( SELECT * ... ) 或使用LEFT JOIN ... IS NULL

【讨论】:

【参考方案2】:

首先,确保您在testmedical 上为id 列建立了索引。应该是PRIMARY KEY

接下来,听起来labtestdata 意味着labidtestid 之间有唯一的关系。假设 labid 通常被称为常量,请确保您在桌子上有一个 UNIQUE 键覆盖 (labid, testid)

我假设这些列都是整数(或 smallint 等)类型。如果它们被定义为 text 或 varchar,那也可能会损害性能。

如果即使在确保拥有这些索引之后查询仍然很慢,请尝试完全避免 WHERE:

INSERT INTO labtestdata
  (labid, testid)
SELECT '131', id
FROM testmedical 
ORDER BY id
ON DUPLICATE KEY UPDATE
  id = VALUES(id);

由于testmedical 表不是很大,希望这会表现良好。但是,在确保您拥有 UNIQUE 密钥的情况下不要运行此程序。

请注意,可能还有其他因素:如果您的实时环境对这些表有大量负载或活动,则它们可能已被锁定,或者此查询加剧了其他性能问题。

【讨论】:

以上是关于编写快速 MySQL INSERT 查询或优化此查询的主要内容,如果未能解决你的问题,请参考以下文章

如何优化Mysql千万级快速分页

MySQL技术专题「性能优化系列」一直都倾向于优化查询,这次学习一下优化Insert插入语句

MySQL优化

MySQL批量SQL插入性能优化

MySQL批量SQL插入性能优化详解

MySQL批量SQL插入各种性能优化