我正在使用mysql multiple-row INSERT syntax将大约3000条记录插入到mysql表中。为了简短的示例,此表只有两列。实际的表当然有更多的列,其中有有意义的索引...
mysql> INSERT INTO table (A, B) VALUES
("constant", 1),
("constant", 2),
("constant", 3);
您可能会注意到 A栏始终是相同的值。
这使我想到了一个实际的问题:是否有办法将 COLUMN A 定义为sql插入语句中的常量,如以下 pseudo code 中所述: / p>
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的字符串(在我的情况下是通过网络发送到)的 然后,当一半的 信息是多余的...恕我直言。如果有 另一种方式-很好。如果不是的话,我会像以前那样…… “对我不舒服”的感觉
答案 0 :(得分:1)
mysql>插入表(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';
您在问题中再次发表了自己的看法:
...假定往返时间为5毫秒作为网络开销。
我认为这是一个不可能的假设。我刚刚测量了我的应用程序在数据中心中的网络延迟,它比您的建议小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进行了比较。