/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
DBI placeholders
Fra : Morten Guldager


Dato : 26-04-04 07:51

Hejsa,

Jeg skriver på et lille program der skal indsætte _mange_
rækker i en MySQL tabel.

I mit program gør jeg sådan her

my $sth2 = $dbh->prepare(<<SQL);
insert
into mogul
(vaerdi)
values (?),(?)
SQL

for at klargøre en sql der kan indsætte 2 rækker ad gangen.

Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
mit program har en ny mængde rækker klar til insert.

Nogen der kender et hack så jeg kan bruge den samme sth
lige godt om jeg har 1, 7 eller 42 rækker jeg gerne vil
sætte ind i et hug?



/Morten

 
 
Tore Aursand (26-04-2004)
Kommentar
Fra : Tore Aursand


Dato : 26-04-04 09:53

On Mon, 26 Apr 2004 06:50:39 +0000, Morten Guldager wrote:
> Jeg skriver på et lille program der skal indsætte _mange_
> rækker i en MySQL tabel.
>
> I mit program gør jeg sådan her
>
> my $sth2 = $dbh->prepare(<<SQL);
> insert
> into mogul
> (vaerdi)
> values (?),(?)
> SQL
>
> for at klargøre en sql der kan indsætte 2 rækker ad gangen.
>
> Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
> mit program har en ny mængde rækker klar til insert.
>
> Nogen der kender et hack så jeg kan bruge den samme sth
> lige godt om jeg har 1, 7 eller 42 rækker jeg gerne vil
> sætte ind i et hug?

Det avhenger litt av hvordan du har informasjonen som skal settes inn
lagret, men generelt sett er jo dette fremgangsmåten;

my $sth = $dbh->prepare( ... );
while ( <DATA> ) {
$sth->execute( ... );
}
$sth->finish();


--
Tore Aursand <tore@aursand.no>
"Then there was the man who drowned crossing a stream with an average
depth of six inches." (W.I.E. Gates)

Kåre Olai Lindbach (26-04-2004)
Kommentar
Fra : Kåre Olai Lindbach


Dato : 26-04-04 10:28

On Mon, 26 Apr 2004 10:52:45 +0200, Tore Aursand <tore@aursand.no>
wrote:

>On Mon, 26 Apr 2004 06:50:39 +0000, Morten Guldager wrote:
>> Jeg skriver på et lille program der skal indsætte _mange_
>> rækker i en MySQL tabel.
>>
>> I mit program gør jeg sådan her
>>
>> my $sth2 = $dbh->prepare(<<SQL);
>> insert
>> into mogul
>> (vaerdi)
>> values (?),(?)
>> SQL
>>
>> for at klargøre en sql der kan indsætte 2 rækker ad gangen.
>>
>> Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
>> mit program har en ny mængde rækker klar til insert.
>>
>> Nogen der kender et hack så jeg kan bruge den samme sth
>> lige godt om jeg har 1, 7 eller 42 rækker jeg gerne vil
>> sætte ind i et hug?
>
>Det avhenger litt av hvordan du har informasjonen som skal settes inn
>lagret, men generelt sett er jo dette fremgangsmåten;
>
> my $sth = $dbh->prepare( ... );
> while ( <DATA> ) {
> $sth->execute( ... );
> }
> $sth->finish();

Jeg tror OP også er ute etter bruk av 'x'-kommandoen, som i

my $insert = 'INSERT INTO mogul (' . join ',',@fields . ')
VALUES (' . join ',', (('?') x @fields) . ')';

.... om nå mine skriveferdigheter, og hukommelse, står meg bi

Så som nevnt av T.A.:
$sth->execute(@values )

@fields er aktuelle tabell-felter, i den andre kunne @values like godt
vært brukt, men de er like store. @values er arrayet med verdier som
matcher @fields.


--
mvh/Regards Kåre Olai Lindbach
(News: Remove '_delete_' and '.invalid')

Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 10:08

Mon, 26 Apr 2004 at 08:52 GMT Tore Aursand wrote
> On Mon, 26 Apr 2004 06:50:39 +0000, Morten Guldager wrote:
>> Jeg skriver på et lille program der skal indsætte _mange_
>> rækker i en MySQL tabel.
>>
>> I mit program gør jeg sådan her
>>
>> my $sth2 = $dbh->prepare(<<SQL);
>> insert
>> into mogul
>> (vaerdi)
>> values (?),(?)
>> SQL
>>
>> for at klargøre en sql der kan indsætte 2 rækker ad gangen.
>>
>> Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
>> mit program har en ny mængde rækker klar til insert.
>>
>> Nogen der kender et hack så jeg kan bruge den samme sth
>> lige godt om jeg har 1, 7 eller 42 rækker jeg gerne vil
>> sætte ind i et hug?
>
> Det avhenger litt av hvordan du har informasjonen som skal settes inn
> lagret, men generelt sett er jo dette fremgangsmåten;
>
> my $sth = $dbh->prepare( ... );
> while ( <DATA> ) {
> $sth->execute( ... );
> }
> $sth->finish();

Jeg tror du misforstod mit problem. Eller også forstår jeg ikke dit svar.

Det er detop det magiske der skal stå hvor du har ... jeg efterlyser.

Mit problem er at jeg skal forberede en hulens masse sth'er for at
tilfredsstille mit programs behov. Bevares, de kan genereres automatisk
efter hånden som programmet for brug for dem. Men det virker klodset.

Sth'en vist ovenfor er jo en special version som netop kan indsætte 2
rækker på en gang. Mit program skal også kunne sætte f.eks. 42 rækker
ind på en gang, eller måske 240 rækker. Ved f.eks. 5 samtidige rækker
kommer min values linje til at se sådan her ud:

values (?),(?),(?),(?),(?)

Lige nu har jeg løst det ved at lade programmet producere en sth når
jeg kender data, og så gemme dem i en cache for det tilfælde at den
skal bruges igen senere.

Tabellen brugt ovenfor er også simplificeret ekstremt, i den virkelige
verden har jeg naturligvis brug for at indsætte data i et antal kolonner.


/Morten

N/A (26-04-2004)
Kommentar
Fra : N/A


Dato : 26-04-04 12:58



Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 12:58

Mon, 26 Apr 2004 at 11:15 GMT Tore Aursand wrote
> On Mon, 26 Apr 2004 09:07:32 +0000, Morten Guldager wrote:

>> Mit problem er at jeg skal forberede en hulens masse sth'er for at
>> tilfredsstille mit programs behov. Bevares, de kan genereres automatisk
>> efter hånden som programmet for brug for dem. Men det virker klodset.
>
> Ok. Så hvis jeg forstår deg riktig så ønsker du å unngå den løkken
> jeg har ovenfor ved å putte "alt" inn i én statement...?
> 'execute_array' kan hjelpe deg med den saken;

Ok, execute_array lignede det helt rigtige. Den er bare endnu langsommere....

I min test fra tidligere bruger execute_array ~26 sekunder på at indsætte
50 batches af 1000 rækker.

Min gamle test med almindelige inserts gav:
- 50000 inserts af 1 række tager ~22 sekunder
- 50 inserts af 1000 rækker tager ~1.7 sekund

Jeg tror nu også vi er på vildspor her. Jeg er "ret sikker" på at mine
multi-row-inserts er den rigtige løsning. Læser man i mysqldump manualen
ser man:

-e|--extended-insert
Use the new multiline INSERT syntax. (Gives more
compact and faster inserts statements.)

Jeg efterlyser bare en fiks måde at gøre det med DBI.


/Morten

N/A (26-04-2004)
Kommentar
Fra : N/A


Dato : 26-04-04 16:41



Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 16:41

Mon, 26 Apr 2004 at 13:51 GMT Tore Aursand wrote
> On Mon, 26 Apr 2004 11:57:38 +0000, Morten Guldager wrote:
>> Ok, execute_array lignede det helt rigtige. Den er bare endnu langsommere....
>
> Selv med 'AutoCommit' slått av?

Ja/nej, jeg bruger MyISAM tabeller. De _kan_ slet ikke transaktioner.

> Jeg har - som sagt - ikke brukt
> 'execute_array' så utrolig mye, men jeg har ikke erfart at den er _så_
> mye langsommere enn noe annet (...).
>
> Men så har jeg aldri prøvd den i forhold til større datamengder, heller.
>
> Uansett så lurer jeg fremdeles på hvordan datastrukturen din ser ut.
> Det er enklere å tilpasse løsningen til datastrukturen, og så lenge jeg
> ikke vet hvordan den ser ut, så...

mysql> desc mogul;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| noegle | int(11) | | PRI | NULL | auto_increment |
| vaerdi | int(11) | YES | | NULL | |
+--------+---------+------+-----+---------+----------------+
2 rows in set (0.02 sec)

> Et veldig enkelt eksempel på multiline-INSERT i forhold til en enkel
> datastruktur (utestet);
>
> my @array = qw( a b c d );
> my $values = join(', ', ('(?)') x @array);
> my $sql = 'INSERT INTO table (character) VALUES ' . $values;
>
> my $sth = $dbh->prepare( $sql );
> $sth->execute( @array );
> $sth->finish();

Og det er vældig meget lig det jeg gør i testen. Se her under:


/Morten



#!/usr/bin/perl -w

use strict;
use DBI;

my $dbh = DBI->connect("DBI:mysql:test:localhost", "mogul", "xxxx");
die "Dumme SQL: $DBI::errstr" unless defined $dbh;


my $ny_metode = 0;

# batch størelse
my $antal = 1000;

my $sth_1 = $dbh->prepare(<<SQL);
insert
into mogul
(vaerdi)
values (?)
SQL

my $liste = join ',', ('(?)') x $antal;
my $sth_n = $dbh->prepare(<<SQL);
insert
into mogul
(vaerdi)
values $liste
SQL


foreach my $n (1..(50000 / $antal))
{
if ($ny_metode)
{
my @l = ($n) x $antal;

my $tuples = $sth_1->execute_array(
{ ArrayTupleStatus => \my @tuple_status }, \@l);
unless ($tuples)
{
print "UN-Successfully inserted $antal records\n";
}
}
else
{
$sth_n->execute(($n) x $antal);
}
}
$dbh->disconnect;


N/A (26-04-2004)
Kommentar
Fra : N/A


Dato : 26-04-04 19:19



Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 19:19

Mon, 26 Apr 2004 at 16:53 GMT Tore Aursand wrote
> On Mon, 26 Apr 2004 15:41:23 +0000, Morten Guldager wrote:
>
> Hmm. Her kan du vel strengt tatt bygge opp _all_ informasjonen du skal
> putte inn i databasen først?

Jo, men al data er ikke kendt for hvert gennemløb.

Nogle gange har jeg data til 5 rækker, andre gange måske 700 rækker.

Jeg vil gerne undgå at skulle prepare en sql for hver eneste batch-størelse
der opstår med tiden.

Jeg ville gerne prepare en _universal_ sql. Som altså ikke er udstyret med
et specifikt antal (?) led.

> my @data;
> for ( 1 .. (50_000/$antal) ) {
> push( @data, ($_) x $antal );
> }
>
> my $val = join(',', ('(?)') x @data);
> my $sth = $dbh->prepare('INSERT INTO mogul (vaerdi) VALUES ' . $val);
> $sth->execute( @data );
> $sth->finish();
>
> Dette tar _under ett sekund_ på min PC;
>
> * AMD 750MHz, 256MB RAM
> * Linux 6.5.5 (blanding av Red Hat/Fedora)
> * MySQL 4.0.18
>
> Mener du at dette ikke er raskt nok?

Jo helt bestemt. Det beviser jo netop min påstand om at inserts med multiple
datasæt er meget hurtigere at udføre for mysql.




/Morten

N/A (27-04-2004)
Kommentar
Fra : N/A


Dato : 27-04-04 06:48



Morten Guldager (27-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 27-04-04 06:48

Mon, 26 Apr 2004 at 19:13 GMT Tore Aursand wrote
> On Mon, 26 Apr 2004 18:19:29 +0000, Morten Guldager wrote:
>> [...]
>> Jeg ville gerne prepare en _universal_ sql. Som altså ikke er udstyret
>> med et specifikt antal (?) led.
>
> Det tror jeg er umulig i ditt tilfelle, såfremt du ønsker maksimal
> hastighet. "Multiline inserts" er det absolutt raskeste, iallfall meg
> bekjent, så da får det heller være at du er nødt til å generere en ny
> SQL-statement for ulike antall batch-verdier.
>
> Hva er egentlig problemet med det?

Der er ikke noget egentligt problem med at generere SQL'er for hver
batch-størelse. Det virker bare lidt besværligt. Og som oftests findes
der en smartere måde at gøre tingene på i perl. Sådan helt generelt...

> Vil du ha både i pose og sekk? :)

Naturligvis!


/Morten

Lasse Hillerøe Peter~ (27-04-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 27-04-04 22:05

In article <slrnc8rt02.dv1.spamtrap@linuxine.mogul.dk>,
Morten Guldager <spamtrap@mogul.dk> wrote:
> > Vil du ha både i pose og sekk? :)
>
> Naturligvis!
>
>
> /Morten

Her er i pose og sæk:
my $MAXPREP = 10;
my $placeholder = '(?)';
for my $i (0 .. $MAXPREP ) {
$sth[$i] = $dbh->prepare("insert into mogul values $placeholder");
$placeholder .= ",$placeholder";
}

# antag at værdier til indsætning er i @array

my ($lower,$remain) = (0, scalar @array);
my $chunk = 2 ** $MAXPREP;
my $level = 10;
while($remain > 0) {
if($remain >= $chunk) {
$sth[$level]->execute_array( { **WHATEVER** }, [ @array[$lower ..
$lower + $chunk -1] ] );
$lower += $chunk;
$remain -= $chunk;
}
else {
$chunk /= 2;
$level--;
}
}

De exakte parametre til execute_array må du selv hitte ud af.

-Lasse

Lasse Hillerøe Peter~ (27-04-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 27-04-04 22:12

In article <lhp+news-4A7B3D.23044427042004@news.tele.dk>,
Lasse Hillerøe Petersen <lhp+news@toft-hp.dk> wrote:
>
> De exakte parametre til execute_array må du selv hitte ud af.
Nå ja, jeg glemmer jo at Balker og Thorbjørn sikkert læser med, så der
skal lige en disclaimer på:

Jeg tager forbehold for enhver fejl, herunder off-by-one fejl, manglende
forståelse for Perl6, der evt måtte findes i den postede kode. Koden
blev postet UTESTET mht anvendelighed med DBI. Enhver brug er på eget
ansvar.

> -Lasse

-Lasse

Morten Guldager (28-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 28-04-04 17:34

Tue, 27 Apr 2004 at 21:04 GMT Lasse Hillerøe Petersen wrote
> In article <slrnc8rt02.dv1.spamtrap@linuxine.mogul.dk>,
> Morten Guldager <spamtrap@mogul.dk> wrote:
>> > Vil du ha både i pose og sekk? :)
>>
>> Naturligvis!
>
> Her er i pose og sæk:
> my $MAXPREP = 10;
> my $placeholder = '(?)';
> for my $i (0 .. $MAXPREP ) {
> $sth[$i] = $dbh->prepare("insert into mogul values $placeholder");
> $placeholder .= ",$placeholder";
> }

Smart ide at forberede et velovervejet udvalg af sth'er.
>
> $sth[$level]->execute_array( { **WHATEVER** }, [ @array[$lower ..
> $lower + $chunk -1] ] );
>
> De exakte parametre til execute_array må du selv hitte ud af.

Jeg forstår nok ikke hvorfor du bruger execute_array og ikke blot execute.

Men det er nok detaljer.


/Morten

Lasse Hillerøe Peter~ (28-04-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 28-04-04 20:54

In article <slrnc8vn7n.ele.spamtrap@linuxine.mogul.dk>,
Morten Guldager <spamtrap@mogul.dk> wrote:

> Jeg forstår nok ikke hvorfor du bruger execute_array og ikke blot execute.
Var det ikke dig der brugte execute_array? Den del af logikken testede
jeg ikke, så der er du på egen hånd.

> Men det er nok detaljer.

Nemlig.

-Lasse

Morten Guldager (29-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 29-04-04 13:40

Wed, 28 Apr 2004 at 19:53 GMT Lasse Hillerøe Petersen wrote
> In article <slrnc8vn7n.ele.spamtrap@linuxine.mogul.dk>,
> Morten Guldager <spamtrap@mogul.dk> wrote:
>
>> Jeg forstår nok ikke hvorfor du bruger execute_array og ikke blot execute.
> Var det ikke dig der brugte execute_array? Den del af logikken testede
> jeg ikke, så der er du på egen hånd.


Ah, jo. execute_array kom ind i billedet, men viste sig midre
egnet end den så ud. (lidt langsommere, lidt mere kompliceret)


/Morten

Lasse Hillerøe Peter~ (29-04-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 29-04-04 12:06

In article <slrnc8vn7n.ele.spamtrap@linuxine.mogul.dk>,
Morten Guldager <spamtrap@mogul.dk> wrote:

> Men det er nok detaljer.

Apropos detaljer, så kunne jeg godt være lidt nysgerrig efter at høre
hvor effektiv metoden egentlig er.

Måske kunne du lokkes til at teste med forskellige antal forberedte
statements? med $MAXPREP = 10 indsætter du max 1024 ad gangen, ca
ligesom du har prøvet (jf den gamle test du nævner i
<slrnc8pu9h.baj.spamtrap@linuxine.mogul.dk>) Sætter du MAXPREP til 1
indsætter du kun 1 ad gangen.
Kunne du evt prøve dette for MAXPREP = 1..16?
Med 50000 inserts skal der ske flg ved MAXPREP = 16:
- Forberede 16 statements. Udføre 6 statements med execute:
- Insert 32768
- Insert 16384
- Insert 512
- Insert 256
- Insert 64
- Insert 16

Det ville være interessant at vide om der er en tradeoff mellem antallet
af forberedte statements og antallet af executes, og om der er en
størrelse af statements der er _for_ stor. (Jeg bemærkede at du ikke
nævner nogen test hvor du indsætter alle 50000 i et hug.)


-Lasse

Morten Guldager (29-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 29-04-04 13:58

Thu, 29 Apr 2004 at 11:06 GMT Lasse Hillerøe Petersen wrote
> In article <slrnc8vn7n.ele.spamtrap@linuxine.mogul.dk>,
> Morten Guldager <spamtrap@mogul.dk> wrote:
>
>> Men det er nok detaljer.
>
> Apropos detaljer, så kunne jeg godt være lidt nysgerrig efter at høre
> hvor effektiv metoden egentlig er.
>
> Måske kunne du lokkes til at teste med forskellige antal forberedte
> statements?

MAXPREP: 4, 3125: inserts 0m5.346s
MAXPREP: 6, 782: inserts 0m4.411s
MAXPREP: 8, 197: inserts 0m2.415s
MAXPREP: 10, 52: inserts 0m2.268s
MAXPREP: 12, 16: inserts 0m2.238s
MAXPREP: 14, 7: inserts 0m2.257s
MAXPREP: 16, 6: inserts 0m2.355s
MAXPREP: 18, 6: inserts 0m2.461s
MAXPREP: 20, 6: inserts 0m3.121s

> (Jeg bemærkede at du ikke nævner nogen test hvor du indsætter alle 50000 i et hug.)

Noget med at min MySQL server ikke vil have uendeligt store sql'er.
Og med 1000 rækker ad gangen er der rigeligt luft til loftet, som vist nok er
default 1 MB.

Testen ovenfor viser forøvrigt også en batch størelse på 1000 rækker i praksis
fungerer godt.



/Morten

Peter Makholm (26-04-2004)
Kommentar
Fra : Peter Makholm


Dato : 26-04-04 10:52

Morten Guldager <spamtrap@mogul.dk> writes:

> for at klargøre en sql der kan indsætte 2 rækker ad gangen.
>
> Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
> mit program har en ny mængde rækker klar til insert.

Kan det virkelig betale sig?

Har du et reelt hastighedsproblem hvis du bare nøjes med at sætte en
række ind ad gangen?


Jeg tror ikke at der er nogen måde at opnå hvad du ønsker. Det eneste
jeg kan finde på er at du kan undgå selv at holde styr på en cache ved
at bruge prepare_cached.

--
Peter Makholm | I have no caps-lock but I must scream...
peter@makholm.net | -- Greg
http://hacking.dk |

Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 11:28

Mon, 26 Apr 2004 at 09:51 GMT Peter Makholm wrote
> Morten Guldager <spamtrap@mogul.dk> writes:
>
>> for at klargøre en sql der kan indsætte 2 rækker ad gangen.
>>
>> Men det er lidt bøvet at jeg skal prepare en ny sql hver gang
>> mit program har en ny mængde rækker klar til insert.
>
> Kan det virkelig betale sig?

Ja.

> Har du et reelt hastighedsproblem hvis du bare nøjes med at sætte en
> række ind ad gangen?

Ja, det slider meget i database serveren, hvilket spreder sig til eventuelle
replikerings slaver.

Jeg har netop udført et par tests:

50000 stk enkelt række inserts: ~22 sekunder
50 stk 1000 række inserts: ~1.7 sekund

> Jeg tror ikke at der er nogen måde at opnå hvad du ønsker. Det eneste
> jeg kan finde på er at du kan undgå selv at holde styr på en cache ved
> at bruge prepare_cached.

Ok, jeg kendte ikke prepare_cached, og den kan da erstatte lidt af
min kode. Men det egentlige problem løser den ikke.



/Morten

Andreas Plesner Jaco~ (26-04-2004)
Kommentar
Fra : Andreas Plesner Jaco~


Dato : 26-04-04 11:41

On 2004-04-26, Morten Guldager <spamtrap@mogul.dk> wrote:
>
>> Har du et reelt hastighedsproblem hvis du bare nøjes med at sætte en
>> række ind ad gangen?
>
> Ja, det slider meget i database serveren, hvilket spreder sig til eventuelle
> replikerings slaver.
>
> Jeg har netop udført et par tests:
>
> 50000 stk enkelt række inserts: ~22 sekunder
> 50 stk 1000 række inserts: ~1.7 sekund

Jeg vil mene at dit problem reelt ligger i at du bruger mysql. Mysql har
ingen funktionalitet til at prepare statements mig bekendt, så dine
statements bliver parset hver gang du kalder execute.

--
Andreas Plesner Jacobsen | "I'm in Pittsburgh. Why am I here?"
|    -- Harold Urey, Nobel Laureate

Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 12:06

Mon, 26 Apr 2004 at 10:40 GMT Andreas Plesner Jacobsen wrote
> On 2004-04-26, Morten Guldager <spamtrap@mogul.dk> wrote:
>>
>>> Har du et reelt hastighedsproblem hvis du bare nøjes med at sætte en
>>> række ind ad gangen?
>>
>> Ja, det slider meget i database serveren, hvilket spreder sig til eventuelle
>> replikerings slaver.
>>
>> Jeg har netop udført et par tests:
>>
>> 50000 stk enkelt række inserts: ~22 sekunder
>> 50 stk 1000 række inserts: ~1.7 sekund
>
> Jeg vil mene at dit problem reelt ligger i at du bruger mysql. Mysql har
> ingen funktionalitet til at prepare statements mig bekendt, så dine
> statements bliver parset hver gang du kalder execute.

Korrekt, udfører jeg blot 50000 prepares uden efterfølgende execute kald
belastes MySQL serveren overhovedet ikke.
Vi kan hurtigt blive enige om at mine problemer sikkert ville være af
en anden art hvis jeg brugte en anden database, eller et andet sprog.

Men her og nu er det altså perl og mysql der er rammerne.

Og mit spørgsmål var en der findes en fiks måde at så prepare til at
forberede en sql med et dynamisk antal række-sæt.

Det lader det ikke til, så jeg koder min egen...


/Morten

N/A (26-04-2004)
Kommentar
Fra : N/A


Dato : 26-04-04 13:48



Andreas Plesner Jaco~ (26-04-2004)
Kommentar
Fra : Andreas Plesner Jaco~


Dato : 26-04-04 13:48

On 2004-04-26, Tore Aursand <tore@aursand.no> wrote:

>> Jeg vil mene at dit problem reelt ligger i at du bruger mysql. Mysql har
>> ingen funktionalitet til at prepare statements mig bekendt, så dine
>> statements bliver parset hver gang du kalder execute.
>
> Nei. Det er DBI-rammeverket som tar seg av denne funksjonaliteten, slik
> at den vil fungere transparent for hver DBD-driver som benyttes.

Ja, men "rigtige" RDBMSer giver DBD mulighed for at parse statements een
gang og udføre flere, det gør mysql ikke.

> 'prepare_cached' kan det være en idé å ta en titt på, men for å være
> ærlig så har jeg aldri opplevd den enorme forskjellen ved å bruke den
> fremfor 'prepare'.

prepare_cached kan vel også betragtes lidt som en bastard, det er nu
engang mere optimalt at holde styr på dine stmt handles selv (i de
fleste situationer, her, hvor vi taler om at arbejde uden om en
uhensigtsmæssighed i den benyttede RDBMS kan prepare_cached selvfølgelig
være et godt alternativ)

--
Andreas Plesner Jacobsen | Big book, big bore.
|    -- Callimachus

Morten Guldager (26-04-2004)
Kommentar
Fra : Morten Guldager


Dato : 26-04-04 16:48

Mon, 26 Apr 2004 at 12:47 GMT Andreas Plesner Jacobsen wrote
> On 2004-04-26, Tore Aursand <tore@aursand.no> wrote:
>
>>> Jeg vil mene at dit problem reelt ligger i at du bruger mysql. Mysql har
>>> ingen funktionalitet til at prepare statements mig bekendt, så dine
>>> statements bliver parset hver gang du kalder execute.
>>
>> Nei. Det er DBI-rammeverket som tar seg av denne funksjonaliteten, slik
>> at den vil fungere transparent for hver DBD-driver som benyttes.
>
> Ja, men "rigtige" RDBMSer giver DBD mulighed for at parse statements een
> gang og udføre flere, det gør mysql ikke.

Jeg har måske ikke det fulde overblik over hvordan stumperne er skruet sammen,
men er DBD ikke en del af kæden der er indlejret i applikationen, og altså
ikke en del af database-serveren?

Bliver forespørgslen (sql'en) maseret/kompileret/massekreret i klientenden inden
den sendes via nettet til serveren?

Jeg ved heller ikke om alle databasesystemer gør den slags på samme vis.



/Morten

Andreas Plesner Jaco~ (29-04-2004)
Kommentar
Fra : Andreas Plesner Jaco~


Dato : 29-04-04 09:14

On 2004-04-26, Morten Guldager <spamtrap@mogul.dk> wrote:
>>
>> Ja, men "rigtige" RDBMSer giver DBD mulighed for at parse statements een
>> gang og udføre flere, det gør mysql ikke.
>
> Jeg har måske ikke det fulde overblik over hvordan stumperne er skruet sammen,
> men er DBD ikke en del af kæden der er indlejret i applikationen, og altså
> ikke en del af database-serveren?

DBD er en del af DBI, ja.

> Bliver forespørgslen (sql'en) maseret/kompileret/massekreret i
> klientenden inden den sendes via nettet til serveren?

Nej, forespørgslen kan blive sendt til serveren til parsing og access
control een gang, og eksekveres flere gange, ganske som prepare/execute
lægger op til.
Bare ikke med mysql (jeg ved desværre ikke hvilke RDBMSer, der
understøtter prepare ordentligt, har kun drifterfaring med Oracle, der
kan, og mysql og postgresql, der ikke kan)

--
Andreas Plesner Jacobsen | question = ( to ) ? be : ! be;
|    -- Wm. Shakespeare

Ask Bjoern Hansen (19-07-2004)
Kommentar
Fra : Ask Bjoern Hansen


Dato : 19-07-04 12:38

Andreas Plesner Jacobsen <apj@daarligstil.dk> writes:

> > 50000 stk enkelt række inserts: ~22 sekunder
> > 50 stk 1000 række inserts: ~1.7 sekund
>
> Jeg vil mene at dit problem reelt ligger i at du bruger mysql. Mysql har
> ingen funktionalitet til at prepare statements mig bekendt,

Fra 4.1 release notes[1]:

New faster client/server protocol that supports prepared statements,
bound parameters, and bound result columns, binary transfer of data,
warnings.


- ask

[1] http://dev.mysql.com/doc/mysql/en/News-4.1.0.html

--
ask bjoern hansen, http://www.askbjoernhansen.com/ !try; do();

Morten Isaksen (26-04-2004)
Kommentar
Fra : Morten Isaksen


Dato : 26-04-04 20:00


"Morten Guldager" <spamtrap@mogul.dk> wrote in message
news:slrnc8pc9v.arc.spamtrap@linuxine.mogul.dk...

> Nogen der kender et hack så jeg kan bruge den samme sth
> lige godt om jeg har 1, 7 eller 42 rækker jeg gerne vil
> sætte ind i et hug?

Det er vist ikke helt det du spørger om, men måske kan du blive inspireret
af nedenstående. Det er ikke det pæneste kode, men det virker, og er noget
hurtigere end enkeltstående sql kald.

while (et eller andet) {
doinsert($srcaddr,$srcport,$dstaddr,$dstport);
}
flushdoinsert();

sub doinsert() {
my ($srcaddr,$srcport,$dstaddr,$dstport) = @_;

if ($c_doinsert == 0) {
$doinsert_val = "('$srcaddr',$srcport,'$dstaddr',$dstport,now())";
}
else {
$doinsert_val = $doinsert_val .
",('$srcaddr',$srcport,'$dstaddr',$dstport,now())";
}
$c_doinsert++;
if ($c_doinsert > 19) {
$statement = "insert into log (srcip,srcport,dstip,dstport,start) values "
.. $doinsert_val;
$dbh->do($statement);
$c_doinsert = 0;
}
}

sub flushdoinsert() {
if ($c_doinsert > 0) {
$statement = "insert into log (srcip,srcport,dstip,dstport,start) values "
.. $doinsert_val;
$sth=$dbh->do($statement);
$doinsert_val = "";
$c_doinsert = 0;
}
}



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408926
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste