Ich arbeite an einem großen PostgreSQL-Projekt, das leider in der Produktion (3 Millionen Datensätze in einer Tabelle mit 90 Spalten) eine Abfrage (ein select/join mit 2 Bedingungen) in etwa 2 Minuten ausführt.PostgreSQL-Optimierung
Angenommen, es gibt nichts zu optimieren auf meine Abfrage, gibt es irgendwelche Einstellungen, die ich ändern könnte, um es schneller laufen zu lassen? Diese ist die Konfiguration der Datenbank, und ich habe keine Ahnung, was meinen Bedürfnissen entspricht:
version PostgreSQL 8.4.4 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44), 32-bit
checkpoint_completion_target 0.9
checkpoint_segments 10
custom_variable_classes pg_stat_statements
effective_cache_size 1GB
lc_collate fr_FR.UTF-8
lc_ctype fr_FR.UTF-8
listen_addresses *
log_autovacuum_min_duration 0
log_line_prefix %t [%p]: [%l-1] user=%u,db=%d
log_min_duration_statement 30s
logging_collector on
maintenance_work_mem 128MB
max_connections 100
max_stack_depth 2MB
pg_stat_statements.max 1000
pg_stat_statements.save on
pg_stat_statements.track all
random_page_cost 1.5
server_encoding UTF8
shared_buffers 128MB
TimeZone Europe/Paris
track_functions pl
wal_buffers 1MB
work_mem 8MB
Abfrage:
SELECT distinct
((Table_Commande_Historique.COD_STECIAL
|| ',' || Table_Commande_Historique.COD_MCIAL
|| ',' || Table_Commande_Historique.NUM_REC_CLI
|| ',' || Table_Commande_Historique.NUM_DNT_CLI
|| ',' || Table_Commande_Historique.NUM_DDE)) cle
FROM G1DDE2_DDE Table_Commande_Historique
inner join "K2VER2_VER" ver
on (Table_Commande_Historique.NUM_REC_CLI
= (string_to_array(ver.num_cle,','))[3]::int
OR Table_Commande_Historique.NUM_DNT_CLI
= (string_to_array(ver.num_cle,','))[3]::int
OR ver.num_cle = (Table_Commande_Historique.COD_MCIAL
|| ',' || Table_Commande_Historique.NUM_REC_CLI)
OR ver.num_cle = (Table_Commande_Historique.COD_MCIAL
|| ',' || Table_Commande_Historique.NUM_DNT_CLI));
Indizes:
CREATE INDEX idx_combo1
ON g1dde2_dde
USING btree
(((cod_mcial || ','::text) || num_rec_cli));
CREATE INDEX idx_combo2
ON g1dde2_dde
USING btree
(((cod_mcial || ','::text) || num_dnt_cli));
CREATE INDEX idx_dnt
ON g1dde2_dde
USING btree
(num_dnt_cli);
CREATE INDEX idx_rec
ON g1dde2_dde
USING btree
(num_rec_cli);
CREATE INDEX idx_k2ver3sb
ON "K2VER2_VER"
USING btree
(num_cle);
ERKLÄREN:
"HashAggregate (cost=197.97..201.77 rows=69 width=29)"
" -> Nested Loop (cost=1.29..197.35 rows=248 width=29)"
" -> Seq Scan on "K2VER2_VER" ver (cost=0.00..2.58 rows=58 width=19)"
" -> Bitmap Heap Scan on g1dde2_dde table_commande_historique (cost=1.29..2.84 rows=5 width=29)"
" Recheck Cond: ((table_commande_historique.num_rec_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer) OR (table_commande_historique.num_dnt_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer) OR ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_rec_cli)::text)) OR ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_dnt_cli)::text)))"
" -> BitmapOr (cost=1.29..1.29 rows=5 width=0)"
" -> Bitmap Index Scan on idx_rec (cost=0.00..0.32 rows=2 width=0)"
" Index Cond: (table_commande_historique.num_rec_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer)"
" -> Bitmap Index Scan on idx_dnt (cost=0.00..0.32 rows=1 width=0)"
" Index Cond: (table_commande_historique.num_dnt_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer)"
" -> Bitmap Index Scan on idx_combo1 (cost=0.00..0.32 rows=1 width=0)"
" Index Cond: ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_rec_cli)::text))"
" -> Bitmap Index Scan on idx_combo2 (cost=0.00..0.32 rows=1 width=0)"
" Index Cond: ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_dnt_cli)::text))"
Zeigen Sie uns Ihre Abfrage, die Tabelle und die Indizes darauf. –
Zeigen Sie die Erklärung ... oder sollen wir raten? –
OK, also sieht es nicht schlecht aus. Die Anzahl der Zeilen ist ziemlich klein. Ist die Erklärung von der Datenbank, wo die Abfrage zu viel Zeit braucht? –