Vax Headroom
2005-11-10 15:56:47 UTC
Salve a tutti...
Mi sto scontrando con uno strano comportamento di una grossa (diciamo pure
enorme) tabella di dati su cui sto utilizzando degli indici... In questa
tabella vengono contenuti dei dati acquisiti in pacchetti di alcuni secondi
l'uno, caratterizzati da uno starttime ed un endtime (conservati come dei
double rappresentanti l'epoch piu` i centesimi di secondo), oltre che da un
nome di canale, piu` un'altra serie di colonne di dati relativi a quel
pacchetto...
Per velocizzare la ricerca all'interno del database ho creato un indice
(btree) implicito creando una chiave primaria proprio sui tre campi in
questione (nome del canale, starttime ed endtime)... Normalmente devo fare
due tipi di quey, la prima e` del tipo:
SELECT starttime, endtime,... FROM rawdata WHERE ( ( channel = 'nome' ) AND
( starttime >= 1128340500 ) AND ( endtime <= 1128340800 ) ) ORDER BY
starttime;
(ho messo dei numeri veri per far capire il tipo di query)
Mentre la seconda e` del tipo:
SELECT starttime, endtime,... FROM rawdata WHERE ( ( channel = 'nome' ) AND
( starttime < 1128340800 ) AND ( endtime > 1128340500 ) ) ORDER BY
starttime;
Le due query, sono quasi identiche, con la differenza che la seconda, a
volte, causa il modo in cui sono impacchettati i dati, puo` restituire una
o due righe in piu`...
Ebbene, sebbene entrambe in un qualche modo usino gli indici (visto che sono
entrambe estremamente piu` veloci in presenza degli stessi), la seconda e`
piuttosto piu` lenta della prima... Ho provato un po' a controllare i piani
di esecuzione delle query, il risultato e` che, se non gliele faccio
esplicitamente eseguire, il planner mi dice che le due query hanno
praticamente lo stesso costo... Se invece forzo l'explain ad eseguirle ho
il risultato "vero" che vi riporto:
EXPLAIN ANALYZE SELECT starttime, endtime, ... FROM RawData WHERE
( ( channel = 'nome' ) AND (starttime >= 1128340500 ) AND ( endtime <=
1128340800 ) );
[cut]
Index Scan using chiaveprimaria on rawdata (cost=0.00..1432061.48
rows=355443 width=531) (actual time=21.370..13795.037 rows=149 loops=1)
Index Cond: (((channel)::text = 'nome'::text) AND (starttime >=
1128340500::double precision) AND (endtime <= 1128340800::double
precision))
Total runtime: 13795.226 ms
(3 righe)
EXPLAIN ANALYZE SELECT starttime, endtime, samplenumber, pinno, samplerate,
datatype, data FROM RawData WHERE ( ( channel = 'nome' ) AND (starttime <
1128340800 ) AND ( endtime > 1128340500 ) );
[cut]
Index Scan using chiaveprimaria on rawdata (cost=0.00..1432065.88
rows=355444 width=531) (actual time=219031.077..219999.047 rows=151
loops=1)
Index Cond: (((channel)::text = 'nome'::text) AND (starttime <
1128340800::double precision) AND (endtime > 1128340500::double precision))
Total runtime: 219999.395 ms
(3 righe)
220 secondi contro 13.8 !!! La differenza mi sembra troppo per non essere
un errore mio nella creazione (e/o configurazione) degli inici... Qualcuno
sa dirmi qualcosa in piu`, e, eventualmente, darmi consigli su come
ulteriormente ottimizzare la ricerca ???
Grazie mille...
Rosario
PS - Allego un po' di statistiche sulla tabella in questione, in questo
momento dovrebbe essere grande piu` o meno come lo sara` "a regime":
SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname =
'rawdata';
relname | relkind | reltuples | relpages
---------+---------+-------------+----------
rawdata | r | 4.25255e+07 | 2657844
(1 riga)
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename =
'rawdata';
attname | n_distinct | most_common_vals
--------------+-------------+---------------------------------------
channel | 12 | {OV.OVO.V,OV.OVO.E,OV.SGG.V,OV.SGG.N}
starttime | 4.06829e+06 | {1125940541}
endtime | 4.06829e+06 | {1125940543}
(altri campi poco utili al discorso)
C'e` pero` da dire che e` ancora in test, a regime il numero di canali sara`
abbastanza piu` grande, circa una settantina...
Mi sto scontrando con uno strano comportamento di una grossa (diciamo pure
enorme) tabella di dati su cui sto utilizzando degli indici... In questa
tabella vengono contenuti dei dati acquisiti in pacchetti di alcuni secondi
l'uno, caratterizzati da uno starttime ed un endtime (conservati come dei
double rappresentanti l'epoch piu` i centesimi di secondo), oltre che da un
nome di canale, piu` un'altra serie di colonne di dati relativi a quel
pacchetto...
Per velocizzare la ricerca all'interno del database ho creato un indice
(btree) implicito creando una chiave primaria proprio sui tre campi in
questione (nome del canale, starttime ed endtime)... Normalmente devo fare
due tipi di quey, la prima e` del tipo:
SELECT starttime, endtime,... FROM rawdata WHERE ( ( channel = 'nome' ) AND
( starttime >= 1128340500 ) AND ( endtime <= 1128340800 ) ) ORDER BY
starttime;
(ho messo dei numeri veri per far capire il tipo di query)
Mentre la seconda e` del tipo:
SELECT starttime, endtime,... FROM rawdata WHERE ( ( channel = 'nome' ) AND
( starttime < 1128340800 ) AND ( endtime > 1128340500 ) ) ORDER BY
starttime;
Le due query, sono quasi identiche, con la differenza che la seconda, a
volte, causa il modo in cui sono impacchettati i dati, puo` restituire una
o due righe in piu`...
Ebbene, sebbene entrambe in un qualche modo usino gli indici (visto che sono
entrambe estremamente piu` veloci in presenza degli stessi), la seconda e`
piuttosto piu` lenta della prima... Ho provato un po' a controllare i piani
di esecuzione delle query, il risultato e` che, se non gliele faccio
esplicitamente eseguire, il planner mi dice che le due query hanno
praticamente lo stesso costo... Se invece forzo l'explain ad eseguirle ho
il risultato "vero" che vi riporto:
EXPLAIN ANALYZE SELECT starttime, endtime, ... FROM RawData WHERE
( ( channel = 'nome' ) AND (starttime >= 1128340500 ) AND ( endtime <=
1128340800 ) );
[cut]
Index Scan using chiaveprimaria on rawdata (cost=0.00..1432061.48
rows=355443 width=531) (actual time=21.370..13795.037 rows=149 loops=1)
Index Cond: (((channel)::text = 'nome'::text) AND (starttime >=
1128340500::double precision) AND (endtime <= 1128340800::double
precision))
Total runtime: 13795.226 ms
(3 righe)
EXPLAIN ANALYZE SELECT starttime, endtime, samplenumber, pinno, samplerate,
datatype, data FROM RawData WHERE ( ( channel = 'nome' ) AND (starttime <
1128340800 ) AND ( endtime > 1128340500 ) );
[cut]
Index Scan using chiaveprimaria on rawdata (cost=0.00..1432065.88
rows=355444 width=531) (actual time=219031.077..219999.047 rows=151
loops=1)
Index Cond: (((channel)::text = 'nome'::text) AND (starttime <
1128340800::double precision) AND (endtime > 1128340500::double precision))
Total runtime: 219999.395 ms
(3 righe)
220 secondi contro 13.8 !!! La differenza mi sembra troppo per non essere
un errore mio nella creazione (e/o configurazione) degli inici... Qualcuno
sa dirmi qualcosa in piu`, e, eventualmente, darmi consigli su come
ulteriormente ottimizzare la ricerca ???
Grazie mille...
Rosario
PS - Allego un po' di statistiche sulla tabella in questione, in questo
momento dovrebbe essere grande piu` o meno come lo sara` "a regime":
SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname =
'rawdata';
relname | relkind | reltuples | relpages
---------+---------+-------------+----------
rawdata | r | 4.25255e+07 | 2657844
(1 riga)
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename =
'rawdata';
attname | n_distinct | most_common_vals
--------------+-------------+---------------------------------------
channel | 12 | {OV.OVO.V,OV.OVO.E,OV.SGG.V,OV.SGG.N}
starttime | 4.06829e+06 | {1125940541}
endtime | 4.06829e+06 | {1125940543}
(altri campi poco utili al discorso)
C'e` pero` da dire che e` ancora in test, a regime il numero di canali sara`
abbastanza piu` grande, circa una settantina...
--
| Almeno tu che puoi fuggi via canto
\|/ ____ \|/ \ ||_| | nomade questa cella e` piena della
"@'/ ,. \`@" \|| | | mia disperazione tu che puoi non
/_| \__/ |_\ Vax Headroom | farti prendere.
\__U_/ | BMS
| Almeno tu che puoi fuggi via canto
\|/ ____ \|/ \ ||_| | nomade questa cella e` piena della
"@'/ ,. \`@" \|| | | mia disperazione tu che puoi non
/_| \__/ |_\ Vax Headroom | farti prendere.
\__U_/ | BMS