我正在开发一个大型 PostgreSQL 项目,不幸的是,在生产中(一个有 90 列的表中有 300 万条记录)在大约 2 分钟内运行一个查询(具有 2 个条件的选择/连接)。
假设我的查询没有什么可以优化的,我可以修改任何设置以使其运行得更快吗?这是数据库的配置,我不知道什么适合我的需求:
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
询问:
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) );
索引:
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 );
解释:
"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))"