Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.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_Query Performance_Mysql Cluster_Percona Xtradb Cluster - Fatal编程技术网

Mysql 插入选择在群集上花费很长时间

Mysql 插入选择在群集上花费很长时间,mysql,query-performance,mysql-cluster,percona-xtradb-cluster,Mysql,Query Performance,Mysql Cluster,Percona Xtradb Cluster,My mysql群集:5.6.30-76.3-56版本,适用于x86_64上的debian linux gnu(Percona XtraDB群集(GPL),rel76.3版,aa929cb修订版,WSREP版本25.16,WSREP_25.16) 我有一个复杂的sql查询,它使用以下语法将大约36k行插入到表中: INSERT INTO `sometable` (SELECT ...); 选择有点复杂,但不慢(0.0023s),但插入大约需要40-50秒。插入行时,该表未被使用 我的问题是:

My mysql群集:
5.6.30-76.3-56版本,适用于x86_64上的debian linux gnu(Percona XtraDB群集(GPL),rel76.3版,aa929cb修订版,WSREP版本25.16,WSREP_25.16)

我有一个复杂的sql查询,它使用以下语法将大约36k行插入到表中:

INSERT INTO `sometable` (SELECT ...);
选择有点复杂,但不慢(0.0023s),但插入大约需要40-50秒。插入行时,该表未被使用

我的问题是:

  • 我能加快速度吗
  • 插入速度慢会导致其他表出现锁定问题(因为select)
  • 这个工作流是好的还是坏的做法?还有更好的吗
谢谢

更新:

表架构:

CREATE TABLE `sometable` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned DEFAULT NULL,
  `a` varchar(255) DEFAULT NULL,
  `b` smallint(6) unsigned DEFAULT NULL,
  `c` smallint(6) unsigned DEFAULT NULL,
  `d` smallint(6) unsigned DEFAULT NULL,
  `e` smallint(6) unsigned DEFAULT NULL,
  `f` varchar(255) DEFAULT '',
  `country_id` int(10) unsigned DEFAULT NULL,
  `city_id` int(10) unsigned DEFAULT NULL,
  `g` smallint(6) unsigned DEFAULT NULL,
  `h` smallint(6) unsigned DEFAULT NULL,
  `i` smallint(6) unsigned DEFAULT NULL,
  `j` smallint(6) unsigned DEFAULT NULL,
  `k` smallint(6) unsigned DEFAULT NULL,
  `l` varchar(3) DEFAULT NULL,
  `m` varchar(3) DEFAULT NULL,
  `n` text,
  `o` varchar(255) DEFAULT NULL,
  `p` varchar(32) DEFAULT NULL,
  `q` varchar(32) DEFAULT NULL,
  `r` varchar(32) DEFAULT NULL,
  `s` time DEFAULT NULL,
  `t` time DEFAULT NULL,
  `u` text,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `country_id` (`country_id`),
  KEY `city_id` (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
更新2:

尝试运行查询时,在某些情况下会出现错误:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
我的解决方案:

如果有人对以下方面感兴趣,以下是我的最终解决方案:


主要问题是,当我填充
mytable
时,其他查询被卡住了,集群出现了严重的性能问题。在这个解决方案中,我创建了一个临时表,并在“脏读”模式下用数据填充它,然后我将这些数据分块复制到
mytable
,这样会花费更多的时间,但不会出现性能问题,也不会阻塞查询。

一个
SELECT
操作非常快,它每64纳秒返回一行您描述的长度。这就是2.3毫秒内36千行的计算结果。您的
SELECT
查询计时似乎没有考虑将结果集传输到MySQL客户端。无论如何,将该性能与插入操作进行比较会使您的期望过高

您可以在开始操作之前尝试发出此命令。它将允许您的
SELECT
操作在
SELECT
的源表上继续处理较少的应用程序流量冲突。看这里

您可以尝试两步流程,包括一个临时表。这样做的好处是不必在执行
SELECT
操作的同时更新
某些表中的所有索引。那次行动将是这样的

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
CREATE TEMPORARY TABLE insert_batch AS SELECT ... ;
INSERT INTO some_table SELECT * FROM insert_batch;
DROP TEMPORARY TABLE insert_batch;

您应该了解InnoDB将批插入作为单个事务发布到表中。如果您可以一次处理500行而不是36K,那么您将有更多的事务,但它们会更小。这通常是获得更高吞吐量的一种方法。

每64纳秒返回一行您描述的长度的
选择操作非常快。这就是2.3毫秒内36千行的计算结果。您的
SELECT
查询计时似乎没有考虑将结果集传输到MySQL客户端。无论如何,将该性能与插入操作进行比较会使您的期望过高

您可以在开始操作之前尝试发出此命令。它将允许您的
SELECT
操作在
SELECT
的源表上继续处理较少的应用程序流量冲突。看这里

您可以尝试两步流程,包括一个临时表。这样做的好处是不必在执行
SELECT
操作的同时更新
某些表中的所有索引。那次行动将是这样的

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
CREATE TEMPORARY TABLE insert_batch AS SELECT ... ;
INSERT INTO some_table SELECT * FROM insert_batch;
DROP TEMPORARY TABLE insert_batch;

您应该了解InnoDB将批插入作为单个事务发布到表中。如果您可以一次处理500行而不是36K,那么您将有更多的事务,但它们会更小。这通常是获得更高吞吐量的一种方法。

如果所有其他方法都失败,这可能是一个可行的解决方案。首先,看

  • 将更正加载到临时表(或非复制MyISAM表)中
  • 循环遍历temp表(使用类似于该链接的代码)。一次选择100行
  • 执行
    插入操作。。。在单独的事务中选择100行中的…
  • 这种技术可能(也可能不)需要超过40-50秒,但至少不太可能超时或死锁


    通常,避免运行任何持续时间超过几秒钟的事务。这个链接是关于如何“分块”冗长(重复)操作以避免冗长事务的通用链接。

    如果所有其他操作都失败,这可能是一个可行的解决方案。首先,看

  • 将更正加载到临时表(或非复制MyISAM表)中
  • 循环遍历temp表(使用类似于该链接的代码)。一次选择100行
  • 执行
    插入操作。。。在单独的事务中选择100行中的…
  • 这种技术可能(也可能不)需要超过40-50秒,但至少不太可能超时或死锁


    通常,避免运行任何持续时间超过几秒钟的事务。这个链接是关于如何“分块”冗长(和重复)操作以避免冗长事务的通用链接。

    与我们分享一下您的表的
    创建表
    语句好吗?(只包括重要的内容,如键、索引列、索引等)请阅读此部分,特别是关于查询性能的部分。那么请回答你的问题。你确定你的
    SELECT
    操作真的那么快吗?请阅读:@O.Jones我已经用模式更新了问题。是的,我已经试过很多次了,选择时间永远不会超过0.003s。如果每次都是手动操作,为什么不
    dump
    数据,编辑并重新插入呢?导入您表格的
    CREATE TABLE
    语句时,与我们分享您的想法不会花费太多时间吗?(只包括重要的内容,如键、索引列、索引等)请阅读此部分,特别是关于查询性能的部分。那么请回答你的问题。你确定你的答案是正确的吗