Thread Insert Into... On Duplicate Key Update... (20 answers)
Opened by rosti at 2012-05-25 20:39

jan
 2012-05-28 10:45
#158649 #158649
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
Der Benchmark ist allerdings sehr mäßig.
a) Du hast bei der autoincr-Tabelle keinen Index auf text.
b) Du löschst jedes mal die tabelle vor einem insert (bei dem einen).
c) Du fragst überflüssigerweise noch mal LAST_INSERT_ID() ab

Ich habe das mal etwas umgestellt (ich habe null ahnung von guten benchmarks, also bitte korrigieren):

Bei nicht-vorhandenen Werten in dem text-Feld (d.h. immer Insert)
Code: (dl )
1
2
3
            Rate AutoIncr Redesign
AutoIncr 20082/s -- -54%
Redesign 43425/s 116% --


bei 50% vorhanden Werten:
Code: (dl )
1
2
3
            Rate AutoIncr Redesign
AutoIncr 35618/s -- -18%
Redesign 43539/s 22% --


bei 100% vorhanden Werten:
Code: (dl )
1
2
3
            Rate AutoIncr Redesign
AutoIncr 33885/s -- -16%
Redesign 40368/s 19% --


Die mysql-spezifische Lösung ist schneller, aber mir bei weitem zu limitiert um sie einzusetzen.


und der Code (mit 50% vorhandenen Werten).

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#/usr/bin/perl

use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use DBI;

my $ins = 'abcde';

my $loop_auto = 0;
my $loop_rosti = 0;

my $DBH = dbh();
my $STH = {
INS_AUTO => $DBH->prepare("INSERT INTO test(text)VALUES(?)"),
IS_DRIN => $DBH->prepare("SELECT id FROM test WHERE text=?"),
LAST_ID => $DBH->prepare("SELECT LAST_INSERT_ID()"),
REDESIGN => $DBH->prepare(q(
INSERT INTO redesign(text)VALUES(?)
ON Duplicate Key UPDATE text=?
)),

};


cmpthese(250000, {
'Redesign' => sub {
$loop_rosti++;
my $test = $ins . ($loop_rosti % 2 ? $loop_rosti : $loop_rosti - 1);
$STH->{REDESIGN}->execute($test, $test);
},
'AutoIncr' => sub {
my $test = $ins . ($loop_auto % 2 ? $loop_auto : $loop_auto - 1);;
$STH->{IS_DRIN}->execute($test);
my $id = 0;
if($id = $STH->{IS_DRIN}->fetchrow_array){
}
else{
$STH->{INS_AUTO}->execute($test);
$id = $STH->{'mysql_insertid'};
}
},
}
);



sub dbh{
my %cfg = (
base => 'testincr',
host => 'localhost',
port => 3306,
user => '',
pass => '',

@_);
my $dbh = undef;
eval{
$dbh = DBI->connect("DBI:mysql:$cfg{base}:$cfg{host}:$cfg{port}", $cfg{user}, $cfg{pass},
{RaiseError => 1, PrintError => 0}
);
};
return $@ ? undef : $dbh;
}

__END__

CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
key(`text`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `redesign` (
`text` varchar(29) NOT NULL DEFAULT '',
PRIMARY KEY (`text`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View full thread Insert Into... On Duplicate Key Update...