mysql多行INSERT语法,其中一个占位符实际上是一个常量

问题描述 投票:0回答:1

我使用mysql multiple-row INSERT syntax将大约3000条记录插入到mysql表中。为了简短的例子,该表只有两列。实际的表当然有更多的列,其中有一个有意义的索引...

mysql> INSERT INTO table (A, B) VALUES 
("constant", 1), 
("constant", 2),
("constant", 3);

您可能会注意到COLUMN A始终是相同的值。

这引出了我的实际问题:是否有一种方法可以将COLUMN A定义为sql insert语句中的常量,如下面的伪代码所述:

mysql> INSERT INTO table (A="constant", B) VALUES 
(1), 
(2),
(3);

准备好的陈述......

现在这个更具体一点。一些实际的perl代码:

#!/usr/bin/perl -W

use strict;
use warnings;
use DBI;

my $dbh = DBI->connect( 'lalalala' );
my $sth = $dbh->prepare( q|INSERT INTO table (A, B) VALUES ("constant",?)| );

foreach my $increment (1 .. 100000){

  $sth->execute( $increment );
}

... 

认为这就是我要找的东西?不幸的是,没有。如前所述,我通过TCP / IP与mysql对话。上面的代码实际上是执行此操作

INSERT INTO table (A, B) VALUES ("constant", 1);
INSERT INTO table (A, B) VALUES ("constant", 2);
etc ...

单个sql查询中的每一个。现在更不用说查询时间假设5ms往返时间作为网络开销。在上面的例子中仅有5个seonds。现在......我已经编写了一个函数来解决这个问题并创建一个紧凑的查询,就像你在这个问题中看到的一样。现在想象一个连接的字符串作为一个带有一百万个插入的查询。好吧它有效。喜欢魅力。但是,通过省略VALUE A来节省大约50%的流量,因为它实际上是一个永不改变的常数值会更好。

如果你想知道为什么我问这个以及这是什么呢?它归结为一件事:将一个正在发送的字符串(在我的情况下通过网络)汇总到mysql,然后当一半的信息是多余的时,它就会被分开以对它做一些事情......而不是高效的imho。如果有另一种方式 - 很好。如果不是我像以前那样做......带着一种“感觉不对我”的感觉

mysql bulkinsert
1个回答
1
投票

mysql> INSERT INTO表(A =“常量”,B)值

不,MySQL中没有这样的语法。这是MySQL中INSERT的语法参考页面:https://dev.mysql.com/doc/refman/8.0/en/insert.html

如果要使用多行INSERT,则必须为每行的元组中的每个列提供一个表达式。表达式在每一行上可以是相同的常量,如原始示例中所示:

mysql> INSERT INTO table (A, B) VALUES 
  ("constant", 1), 
  ("constant", 2),
  ("constant", 3);

或者它可以是一个会话变量(如上面评论的@wchiquito)。

mysql> SET @c = 'constant';
mysql> INSERT INTO table (A, B) VALUES 
  (@c, 1), 
  (@c, 2),
  (@c, 3);

或者您可以将值加载到临时表中,然后将它们复制到最终表(由上面的Mauricio Javier Biott评论):

mysql> CREATE TEMPORARY TABLE temptable (B INT);
mysql> INSERT INTO temptable (A, B) VALUES 
  (1), 
  (2),
  (3);
mysql> INSERT INTO table (A, B) 
  SELECT 'constant', B FROM temptable;

这是另一种解决方案。假设data.txt仅包含每行需要具有不同值的字段,则可以使用LOAD DATA LOCAL INFILE,并在最终的SET子句中设置不变列。

mysql> LOAD DATA LOCAL INFILE 'data.txt' 
  INTO TABLE mytable (B) 
  SET A = 'constant';

你在问题中又发表了一个声明:

...假设5ms往返时间作为网络开销。

我认为这是一个不可能的假设。我刚刚在我的数据中心测量了我的应用程序的网络延迟,它比你建议的小36到50倍。

64 bytes from (10.4.12.100): icmp_seq=1 ttl=64 time=0.112 ms
64 bytes from (10.4.12.100): icmp_seq=2 ttl=64 time=0.138 ms
64 bytes from (10.4.12.100): icmp_seq=3 ttl=64 time=0.103 ms
64 bytes from (10.4.12.100): icmp_seq=4 ttl=64 time=0.108 ms
...

这是每次往返十分之一毫秒,而不是5毫秒。

执行准备语句3000次的网络延迟最多为414毫秒,而不是3000 * 5ms = 15秒。如果网络延迟使您的任务具有不可接受的开销,则需要改进网络。

最后,您可能希望看到我为演示文稿Load Data Fast!所做的基准测试我将单行INSERT与多行INSERT与LOAD DATA进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.