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

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Omskrivning/optimering af SQL/index ???
Fra : Jesper Frank Nemholt


Dato : 26-04-02 16:02

Hej!

Jeg har følgende query :

SELECT substring_index(picasso.timecode,':',1),
avg(picasso.usertime + picasso.systemtime) AS picasso,
avg(matisse.usertime + matisse.systemtime)AS matisse
FROM cpu AS picasso, cpu AS matisse
WHERE picasso.systemid='3'
AND matisse.systemid='2'
AND substring_index(picasso.timecode,':',1) =
substring_index(matisse.timecode,':',1)
AND picasso.timecode > now() - INTERVAL 7 DAY
AND matisse.timecode > now() - INTERVAL 7 DAY
GROUP BY substring_index(picasso.timecode,':',1)
ORDER BY substring_index(picasso.timecode,':',1)


Table bagved ser således ud :

mysql> desc cpu;
+-----------------+----------------------+------+-----+---------------------
+-------+
| Field | Type | Null | Key | Default
| Extra |
+-----------------+----------------------+------+-----+---------------------
+-------+
| timecode | datetime | | MUL | 0000-00-00 00:00:00
| |
| systemid | smallint(5) unsigned | | | 0
| |
| usertime | float(3,1) | YES | | NULL
| |
| systemtime | float(3,1) | YES | | NULL
| |
| waittime | float(3,1) | YES | | NULL
| |
| idletime | float(3,1) | YES | | NULL
| |
| runqueue60 | float(4,2) | YES | | NULL
| |
| processes | smallint(5) unsigned | YES | | NULL
| |
| interrupts | float(6,1) | YES | | NULL
| |
| systemcalls | float(6,1) | YES | | NULL
| |
| contextswitches | float(6,1) | YES | | NULL
| |
+-----------------+----------------------+------+-----+---------------------
+-------+
11 rows in set (0.00 sec)


....og har følgende index :

mysql> show index from cpu;
+-------+------------+----------+--------------+-------------+-----------+--
-----------+----------+--------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation |
Cardinality | Sub_part | Packed | Comment |
+-------+------------+----------+--------------+-------------+-----------+--
-----------+----------+--------+---------+
| cpu | 1 | timecode | 1 | timecode | A |
44530 | NULL | NULL | |
| cpu | 1 | timecode | 2 | systemid | A |
44530 | NULL | NULL | |
+-------+------------+----------+--------------+-------------+-----------+--
-----------+----------+--------+---------+
2 rows in set (0.06 sec)

Kan testes/afprøves live her :

http://statdb.dassic.com/sql.php

....og forneden her (dette interface laver PNG grafer. Timecode er påkrævet
som første række) :

http://statdb.dassic.com/scripts/graphics_interface_advanced.php

(og ja, der er kun select adgang <g>)

Mit problem er at den query er langsom. Givetvis fordi min viden om SQL er
temmelig begrænset...så hvis nogen har en idé til hvordan jeg kan optimere
SQL'en eller index til at køre hurtigere.
En detalje er at jeg gerne vil kunne tilføje flere maskiner i SQL'en så man
f.eks. får 3 eller 4 maskiner i samme graf.
Den kører nogenlunde på min egen maskine da databasen er lille og der kun er
4 maskiner, men på mit arbejde er basen adskillige GB og der er > 100
maskiner og her går der på den forkerte side af 4 minutter til trods for at
database serveren er en rimelig hurtig Alpha med 4 CPU'er & 4 GB RAM.

Jeg bruger substring_index() da timecode for de 2 maskiner ikke er
synkroniseret. De sender data individuelt. Derfor tages average over en time
istedet (der logges hvert 5. minut).

MySQL er version 3.23.49 og tables er InnoDB. Maskinen bag statdb.dassic.com
er en dual P3 med 1 GB RAM.
Settings for databasen kan ses ved at fyre "show variables", "show status",
"show processlist" af i sql interfacet.


/Jesper



 
 
Stig Johansen (26-04-2002)
Kommentar
Fra : Stig Johansen


Dato : 26-04-02 16:42

Jesper Frank Nemholt wrote:

> Hej!
>
> Jeg har følgende query :
>
> SELECT substring_index(picasso.timecode,':',1),
> avg(picasso.usertime + picasso.systemtime) AS picasso,
> avg(matisse.usertime + matisse.systemtime)AS matisse
> FROM cpu AS picasso, cpu AS matisse
> WHERE picasso.systemid='3'
> AND matisse.systemid='2'
> AND substring_index(picasso.timecode,':',1) =
> substring_index(matisse.timecode,':',1)

[klip]

> Jeg bruger substring_index() da timecode for de 2 maskiner ikke er
> synkroniseret. De sender data individuelt. Derfor tages average over en
> time istedet (der logges hvert 5. minut).

Din join er baseret på funktioner. Derfor kan optimizeren ikke benytte
indexer på joinen.

Selvom du synkroniserer tiden, vel den nok ikke være præcis ned på 1 sek. Du
kan derfor gemme den afrundede tid i stedet for den rigtige tid, og
benytte:
....
AND picasso.timecode = matisse.timecode

Hvis du har brug for den rigtige tid, kan du oprette et felt med den
afrundede tid, og benytte dette i stedet.

Jeg kender ikke mySQL, men der er nogle databasesystemer, hvor optimizeren
er glad for du skriver din join i stedet for at benytte implicit join.

--
Med venlig hilsen / Best regards
Stig Johansen
stig.johansen@udvikling.it.dk
(remove dot dk)

Jesper Frank Nemholt (26-04-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 26-04-02 17:07

"Stig Johansen" <stig.johansen@udvikling.it> wrote in message
news:aabsg1$nsl$1@sunsite.dk...
> Jesper Frank Nemholt wrote:
>
> > Hej!
> >
> > Jeg har følgende query :
> >
> > SELECT substring_index(picasso.timecode,':',1),
> > avg(picasso.usertime + picasso.systemtime) AS picasso,
> > avg(matisse.usertime + matisse.systemtime)AS matisse
> > FROM cpu AS picasso, cpu AS matisse
> > WHERE picasso.systemid='3'
> > AND matisse.systemid='2'
> > AND substring_index(picasso.timecode,':',1) =
> > substring_index(matisse.timecode,':',1)
>
> [klip]
>
> > Jeg bruger substring_index() da timecode for de 2 maskiner ikke er
> > synkroniseret. De sender data individuelt. Derfor tages average over en
> > time istedet (der logges hvert 5. minut).
>
> Din join er baseret på funktioner. Derfor kan optimizeren ikke benytte
> indexer på joinen.
>
> Selvom du synkroniserer tiden, vel den nok ikke være præcis ned på 1 sek.
Du
> kan derfor gemme den afrundede tid i stedet for den rigtige tid, og
> benytte:
> ...
> AND picasso.timecode = matisse.timecode

Jo, jeg har overvejet at lave en "select into blabla" over i en temporær
tabel for hver maskine med afrundet tid så tidskoderne er ens for alle
maskiner.
Herefter kan jeg gøre som du foreslår og sammenligne tidskoderne uden brug
af funktioner.

/Jesper



Stig Johansen (26-04-2002)
Kommentar
Fra : Stig Johansen


Dato : 26-04-02 17:38

Jesper Frank Nemholt wrote:

[klip]
> Jo, jeg har overvejet at lave en "select into blabla" over i en temporær
> tabel for hver maskine med afrundet tid så tidskoderne er ens for alle
> maskiner.
> Herefter kan jeg gøre som du foreslår og sammenligne tidskoderne uden brug
> af funktioner.

Kan du ikke bare afrunde tiden i dit 'logger' program?.

--
Med venlig hilsen / Best regards
Stig Johansen
stig.johansen@udvikling.it.dk
(remove dot dk)

Jesper Frank Nemholt (26-04-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 26-04-02 17:51

"Stig Johansen" <stig.johansen@udvikling.it> wrote in message
news:aabvpb$2em$1@sunsite.dk...
> Jesper Frank Nemholt wrote:
>
> [klip]
> > Jo, jeg har overvejet at lave en "select into blabla" over i en temporær
> > tabel for hver maskine med afrundet tid så tidskoderne er ens for alle
> > maskiner.
> > Herefter kan jeg gøre som du foreslår og sammenligne tidskoderne uden
brug
> > af funktioner.
>
> Kan du ikke bare afrunde tiden i dit 'logger' program?.

Tjo, men så er der bare nogen der bliver sure fordi de logger med et andet
interval end de 5 minutter jeg selv bruger per default.


/Jesper



Stig Johansen (26-04-2002)
Kommentar
Fra : Stig Johansen


Dato : 26-04-02 17:57

Jesper Frank Nemholt wrote:

> Tjo, men så er der bare nogen der bliver sure fordi de logger med et andet
> interval end de 5 minutter jeg selv bruger per default.

Det er ikke sikkert, jeg helt forstår din problemstilling, men har du ikke
mulighed for at tilføje et ekstra felt, eks. timecode_ix, der indeholder
den afrundede tid.
Så kan du i dit statistikprogram bruge:
....
AND picasso.timecode_ix = matisse.timecode_ix
....
samtidig med du bibeholder den aktuelle tid i timecode.

Det burde ikke påvirke andre dele af applikationen.

--
Med venlig hilsen / Best regards
Stig Johansen
stig.johansen@udvikling.it.dk
(remove dot dk)

Jesper Frank Nemholt (27-04-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 27-04-02 10:01

"Stig Johansen" <stig.johansen@udvikling.it> wrote in message
news:aac0sb$7fo$1@sunsite.dk...
> Jesper Frank Nemholt wrote:
>
> > Tjo, men så er der bare nogen der bliver sure fordi de logger med et
andet
> > interval end de 5 minutter jeg selv bruger per default.
>
> Det er ikke sikkert, jeg helt forstår din problemstilling, men har du ikke
> mulighed for at tilføje et ekstra felt, eks. timecode_ix, der indeholder
> den afrundede tid.
> Så kan du i dit statistikprogram bruge:
> ...
> AND picasso.timecode_ix = matisse.timecode_ix
> ...
> samtidig med du bibeholder den aktuelle tid i timecode.
>
> Det burde ikke påvirke andre dele af applikationen.

Det var en mulighed. Jeg kan jo prøve det ret nemt ved at lave en alter
table og så lave en update bagefter på de eksisterende data hvor jeg
indsætter den afrundede tidskode i det nye felt.

Jeg skal så bare ændre i web interfacet så det springer over begge
tidskoder.
Pt fungerer web interfacet således at en given SQL query fyres af uden at
blive analyseret. Herefter bruger jeg metadata til at finde ud af hvad jeg
har fået tilbage og char/varchar/varchar2 felter bliver så lavet til html
select menuer mens timecode springes over.


/Jesper



Jesper Frank Nemholt (29-04-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 29-04-02 17:53

"Jesper Frank Nemholt" <jfn@dassic.com> wrote in message
news:aadpgi$mqs$1@sunsite.dk...
> "Stig Johansen" <stig.johansen@udvikling.it> wrote in message
> news:aac0sb$7fo$1@sunsite.dk...
> > Jesper Frank Nemholt wrote:
> >
> > > Tjo, men så er der bare nogen der bliver sure fordi de logger med et
> andet
> > > interval end de 5 minutter jeg selv bruger per default.
> >
> > Det er ikke sikkert, jeg helt forstår din problemstilling, men har du
ikke
> > mulighed for at tilføje et ekstra felt, eks. timecode_ix, der indeholder
> > den afrundede tid.
> > Så kan du i dit statistikprogram bruge:
> > ...
> > AND picasso.timecode_ix = matisse.timecode_ix
> > ...
> > samtidig med du bibeholder den aktuelle tid i timecode.
> >
> > Det burde ikke påvirke andre dele af applikationen.
>
> Det var en mulighed. Jeg kan jo prøve det ret nemt ved at lave en alter
> table og så lave en update bagefter på de eksisterende data hvor jeg
> indsætter den afrundede tidskode i det nye felt.
>
> Jeg skal så bare ændre i web interfacet så det springer over begge
> tidskoder.
> Pt fungerer web interfacet således at en given SQL query fyres af uden at
> blive analyseret. Herefter bruger jeg metadata til at finde ud af hvad jeg
> har fået tilbage og char/varchar/varchar2 felter bliver så lavet til html
> select menuer mens timecode springes over.

Apropos det med at afrunde tiden så kom jeg til at tænke på at jeg
principielt intet taber ved at afrunde til det interval der samples med,
d.v.s. hvis jeg kører med 5 minutters interval så kan jeg afrunde
tidskoderne til 5,10,15,20,25 o.s.v. for alle systemer og så kan jeg undgå
substring_index() og/eller ekstra afrundet felt.
.....det fremprovokoerer så lige en lille feature som enten skal laves i SQL
eller Perl :

Hvordan får man let og elegant afrundet en tidskode i formatet YYYY-MM-DD
HH.MM.SS til nærmeste X, hvor X er det interval man angiver, f.eks. 300
sekunder (5. minutter) således at en tidskode a la 2002-04-29 15:04:23
bliver til 2002-04-29 15:05:00 for et interval på 5 minutter men 2002-04-29
15:04:00 for et interval på 1 minut.

Jeg er overbevist om at dette kan laves kort og smart, ihvertfald i Perl,
men har ikke lige på stående fod en idé..... anyone ?
I SQL har jeg slet ingen idé.

/Jesper



Dennis Haney (29-04-2002)
Kommentar
Fra : Dennis Haney


Dato : 29-04-02 18:14

"Jesper Frank Nemholt" <jfn@dassic.com> writes:
>
> Hvordan får man let og elegant afrundet en tidskode i formatet YYYY-MM-DD
> HH.MM.SS til nærmeste X, hvor X er det interval man angiver, f.eks. 300
> sekunder (5. minutter) således at en tidskode a la 2002-04-29 15:04:23
> bliver til 2002-04-29 15:05:00 for et interval på 5 minutter men 2002-04-29
> 15:04:00 for et interval på 1 minut.
>
> Jeg er overbevist om at dette kan laves kort og smart, ihvertfald i Perl,
> men har ikke lige på stående fod en idé..... anyone ?

300*(time()/300) (heltals beregninger). Bemærk dette skal skrives i
perl som 300*int(time()/300)

> I SQL har jeg slet ingen idé.

Ovenstående burde virke fint med modifikationer.


--
Dennis
I too have always thought explanations were overkill when correcting peoples
mistake... A simple "that's wrong" has to suffice. I mean, people are always
aware why they are wrong... They just make mistakes to annoy you...

Lars Balker Rasmusse~ (29-04-2002)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 29-04-02 18:30

Dennis Haney <davh@diku.dk> writes:
> 300*(time()/300) (heltals beregninger). Bemærk dette skal skrives i
> perl som 300*int(time()/300)

Runder kun ned - hvis den skal virke, skal du lægge 150 til time().

Nedenstående konverterer også:

#!/usr/local/bin/perl -lw
use strict;

use POSIX qw(strftime);
use Time::Local;

sub dateround($$) {
my ($date, $round) = @_;

my $sec = timelocal(reverse split /\D+/, $date);
$sec += $round / 2;
$sec -= $sec % $round;

strftime "%Y-%m-%d %H:%M:%S", localtime($sec);
}

print dateround "2002-04-29 15:04:23", 300;
print dateround "2002-04-29 15:04:23", 60;
--
Lars Balker Rasmussen "Special is bad."

Jesper Frank Nemholt (29-04-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 29-04-02 18:37

"Lars Balker Rasmussen" <lars@balker.org> wrote in message
news:0fit6axvis.fsf@humulus.daimi.au.dk...
> Dennis Haney <davh@diku.dk> writes:
> > 300*(time()/300) (heltals beregninger). Bemærk dette skal skrives i
> > perl som 300*int(time()/300)
>
> Runder kun ned - hvis den skal virke, skal du lægge 150 til time().
>
> Nedenstående konverterer også:
>
> #!/usr/local/bin/perl -lw
> use strict;
>
> use POSIX qw(strftime);
> use Time::Local;
>
> sub dateround($$) {
> my ($date, $round) = @_;
>
> my $sec = timelocal(reverse split /\D+/, $date);
> $sec += $round / 2;
> $sec -= $sec % $round;
>
> strftime "%Y-%m-%d %H:%M:%S", localtime($sec);
> }
>
> print dateround "2002-04-29 15:04:23", 300;
> print dateround "2002-04-29 15:04:23", 60;

Bukker dybt og takker :)
En virtuel 6pack Mahou (lokal øl) er hermed sendt til det kolde nord.

/Jesper



Jesper Frank Nemholt (03-05-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 03-05-02 15:53

"Lars Balker Rasmussen" <lars@balker.org> wrote in message
news:0fit6axvis.fsf@humulus.daimi.au.dk...
> Dennis Haney <davh@diku.dk> writes:
> > 300*(time()/300) (heltals beregninger). Bemærk dette skal skrives i
> > perl som 300*int(time()/300)
>
> Runder kun ned - hvis den skal virke, skal du lægge 150 til time().
>
> Nedenstående konverterer også:
>
> #!/usr/local/bin/perl -lw
> use strict;
>
> use POSIX qw(strftime);
> use Time::Local;
>
> sub dateround($$) {
> my ($date, $round) = @_;
>
> my $sec = timelocal(reverse split /\D+/, $date);
> $sec += $round / 2;
> $sec -= $sec % $round;
>
> strftime "%Y-%m-%d %H:%M:%S", localtime($sec);
> }
>
> print dateround "2002-04-29 15:04:23", 300;
> print dateround "2002-04-29 15:04:23", 60;


.....og lægger en måned til


/Jesper



Lars Balker Rasmusse~ (03-05-2002)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 03-05-02 19:20

"Jesper Frank Nemholt" <jfn@dassic.com> writes:
> ....og lægger en måned til

Hov!

> > my $sec = timelocal(reverse split /\D+/, $date);

my @date = split /\D+/, $date;
--$date[1]; # timelocal wants zero-based months
my $sec = timelocal(reverse @date);

Bedre? :)
--
Lars Balker Rasmussen                  "S.M.R.T."

Jesper Frank Nemholt (05-05-2002)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 05-05-02 13:23

"Lars Balker Rasmussen" <lars@balker.org> wrote in message
news:ulmb1ccw2.fsf@laphroaig.balker.org...
> "Jesper Frank Nemholt" <jfn@dassic.com> writes:
> > ....og lægger en måned til
>
> Hov!
>
> > > my $sec = timelocal(reverse split /\D+/, $date);
>
> my @date = split /\D+/, $date;
> --$date[1]; # timelocal wants zero-based months
> my $sec = timelocal(reverse @date);
>
> Bedre? :)

Jeps.



Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408526
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste