繁体   English   中英

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

[英]mysql multiple-row INSERT syntax where one placeholder is actually a constant

我正在使用mysql多行INSERT语法将大约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的往返时间为网络开销。 在上面的示例中,仅这五个就可以了。 现在...我编写了一个函数来解决这个混乱,并创建了一个紧凑的查询,就像您在此问题的顶部看到的那样。 现在,将一个简短的字符串想象成一个具有一百万次插入的查询。 好吧。 像个魅力。 但是,通过省略VALUE A可以节省大约50%的流量,因为它实际上是一个不变的值,永远不变。

圣经后

如果您想知道为什么我问这个,这是什么意思? 它归结为一件事:将beeing的字符串(在我的情况下是通过网络)发送给mysql,然后在一半的信息是多余的时候bee被bee拆分以对其进行处理...恕我直言。 如果还有另一种方法-很好。 如果不是,我会像以前那样……带着“对我不舒服”的感觉

mysql> INSERT INTO表(A =“ constant”,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秒。 如果网络延迟使您的任务产生不可接受的开销,则需要改进网络。

最后,您可能想看看我在演示中所做的基准测试,即“ 快速加载数据”! 我比较了单行INSERT与多行INSERT与LOAD DATA。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM