Hello, If possible, I would need your help/suggestions for this problem : I'm experiencing a serious performance problem using postgresql foreign data wrapper. In particular, a simple query performed via fdw lasts 80 times more than the same query performed directly on the local server. Here are the details : I have two postgresql servers both located on the same server farm, based on Vmware Esxi 5.1. They're communicating directly on the same subnet, so network should't interfere with performance. On the first server, which I'll call LOCAL, I defined a postgres_fdw foreign server pointing to the other server, which I'll call REMOTE. Both servers are running Postgresql 9.3.5 (see bottom for complete details on server configuration) On the local server I defined a foreign table "v_mdn_colli_testata" pointing to the remote server. The foreign table is defined in this way : CREATE FOREIGN TABLE logimat.v_mdn_colli_testata (id bigint , collo character varying(20) ,
stato character(1) , id_spedizione bigint , id_es_rientro bigint , peso numeric(15,3) ,
volume numeric(15,3) , ordine character varying(20) , data timestamp without time zone , capoconto text , conto text , causale character varying(10) , descrizione character varying(50) , tipo character varying(10) ,
capoconto_v text , conto_v text , magazzino character varying(5) , tipo_spedizione integer , data_spedizione date , consegna_spedizione character varying(2) ,
documento character varying(20) , data_documento timestamp without time zone , borderau character varying(15) , data_borderau timestamp without time zone ) SERVER fdw_remote_server OPTIONS (schema_name 'public', table_name 'v_mdn_colli_testata'); ALTER FOREIGN TABLE logimat.v_mdn_colli_testata OWNER TO dba;
The table pointed on the remote server by the foreign table is actually a view defined in this way : CREATE OR REPLACE VIEW v_mdn_colli_testata AS
SELECT uds.id, uds.codice AS collo,
uds.flag1 AS stato, uds.id_spedizione,
uds.id_reso AS id_es_rientro,
uds.peso_netto AS peso, uds.volume, o.ordine, o.data, "substring"(o.destinatario::text, 1, 6) AS capoconto, "substring"(o.destinatario::text, 7, 7) AS conto, o.causale, o.desc_causale AS descrizione, o.tipo_ordine AS tipo,
"substring"(o.corriere::text, 1, 6) AS capoconto_v, "substring"(o.corriere::text, 7, 7) AS conto_v,
o.magazzino_prespedizione AS magazzino, o.priorita_codice AS tipo_spedizione, o.priorita_data AS data_spedizione, o.priorita_consegna AS consegna_spedizione, doc.ddt AS documento, doc.data_ddt AS data_documento, doc.borderau, doc.data_borderau FROM ordine_allestimento o
LEFT JOIN allestimento al ON o.azienda::text = al.azienda::text AND o.divisione::text = al.divisione::text AND o.sezione::text = al.sezione::text AND o.ordine::text = al.ordine::text
AND o.riga::text = al.riga::text LEFT JOIN azienda az ON az.codice::text = o.azienda::text LEFT JOIN soggetto s ON s.id_azienda = az.id AND s.soggetto::text = o.destinatario::text LEFT JOIN lista_allestimento_riga lr ON lr.id = al.id_riga_lista LEFT JOIN lista_allestimento la ON la.id = lr.id_lista LEFT JOIN documento_riga dr ON dr.id_riga_lista = lr.id LEFT JOIN documento doc ON doc.id = dr.id_documento LEFT JOIN packing_list_riga pr ON pr.id_riga_lista = lr.id LEFT JOIN oper_pian op ON op.id = pr.id_oper_pian LEFT JOIN uds ON uds.id = pr.id_uds LEFT JOIN packing_list pl ON pl.id = uds.id_packing_list WHERE la.id_tipo_lista = 147916620 AND uds.id IS NOT NULL;
And here's is the problem : on the REMOTE SERVER, the query : select * from public.v_mdn_colli_testata where collo='U0019502'
has an execution time slightly greater than 100 ms : INFOLOG=# select * from public.v_mdn_colli_testata where collo='U0019502'; -[ RECORD 1 ]-------+------------------------------ id | 165999157 collo | U0019502 stato | P id_spedizione | id_es_rientro | peso | 0.500 volume | 0.000 ordine | 001824 data | 2015-01-08 16:56:03.714 capoconto | 000100 conto | 0001401 causale | PMP descrizione | INVIO MATERIALE PUBBLICITARIO tipo | ORDT capoconto_v | 000200 conto_v | 0006128 magazzino | 00039 tipo_spedizione | 0 data_spedizione | consegna_spedizione | documento | 00000026 data_documento | 2015-01-09 15:54:17.706 borderau | 00003212 data_borderau | 2015-01-09 00:00:00 Time: 104.907 ms *************************************************************** on the LOCAL server instead, the same query performed on the foreign table lasts much longer : mdn=# select * from logimat.v_mdn_colli_testata where collo='U0019502'; -[ RECORD 1 ]-------+------------------------------ id | 165999157 collo | U0019502 stato | P id_spedizione | id_es_rientro | peso | 0.500 volume | 0.000 ordine | 001824 data | 2015-01-08 16:56:03.714 capoconto | 000100 conto | 0001401 causale | PMP descrizione | INVIO MATERIALE PUBBLICITARIO tipo | ORDT capoconto_v | 000200 conto_v | 0006128 magazzino | 00039 tipo_spedizione | 0 data_spedizione | consegna_spedizione | documento | 00000026 data_documento | 2015-01-09 15:54:17.706 borderau | 00003212 data_borderau | 2015-01-09 00:00:00 Time: 9887.533 ms *************************************************************** Both query were issued repeatedly to get rid of disk access and database connection overhead time. Activating duration and statement logging on the remote server I can see that the query issued through the fdw from the LOCAL SERVER is actually performed by opening a cursor : 2015-01-14 13:53:31 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: statement: START TRANSACTION ISOLATION LEVEL REPEATABLE READ 2015-01-14 13:53:31 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: execute <unnamed>: DECLARE c1 CURSOR FOR SELECT id, collo, stato, id_spedizione, id_es_rientro, peso,
volume, ordine, data, capoconto, conto, causale, descrizione, tipo, capoconto_v, conto_v, magazzino, tipo_spedizione, data_spedizione, consegna_spedizione, documento, data_documento, borderau, data_borderau FROM public.v_mdn_colli_testata WHERE ((collo = 'U0019502'::text)) 2015-01-14 13:53:31 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: statement: FETCH 100 FROM c1 2015-01-14 13:53:41 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: duration: 9887.533 ms 2015-01-14 13:53:41 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: statement: CLOSE c1 2015-01-14 13:53:41 GMT 192.168.2.31(58031) mdn INFOLOG 0 54b64297.327c - LOG: statement: COMMIT TRANSACTION My questions are : IS THIS THE EXPECT BEHAVIOUR ?
IS THERE ANY WAY TO MODIFY IT AND IMPROVE THE PERFORMANCE ? I hope everything is clear THANKS VERY MUCH IN ADVANCE Marco
I include information about my environment : HARDWARE: --------- Both servers are virtual machines running on Vmware Esxi 5.1 LOCAL : 2 vCpu Intel Xeon E5-2690v2 3.00 Ghz , 6GB RAM REMOTE : 2 cpu, Intel Xeon E7-2860 2.27 GHz , 6GB RAM Storage on SAN-based datastore POSTGRESQL VERSION : --------------------- LOCAL SERVER : PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3), 64-bit REMOTE SERVER: PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3), 64-bit Postgresql compiled from source with :
OPTIONS :
./configure --with-python --with-gssapi --with-krb-srvnam=POSTGRES MODULES :
- pg_upgrade - adminpack - pg_upgrade_support - pgrowlocks - pg_archivecleanup - pg_test_fsync - pg_buffercache - postgres_fdw - pg_buffercache.sql - itcodes/italian_codes
POSTGRESQL CONFIGURATION : --------------------------- LOCAL SERVER: mdn=# SELECT name, current_setting(name), source mdn-# FROM pg_settings mdn-# WHERE source NOT IN ('default', 'override'); name | current_setting | source --------------------------------+--------------------------------+---------------------- application_name | psql | client autovacuum | on | configuration file autovacuum_max_workers | 7 | configuration file autovacuum_naptime | 10min | configuration file autovacuum_vacuum_cost_delay | 20ms | configuration file autovacuum_vacuum_cost_limit | 200 | configuration file bytea_output | escape | configuration file checkpoint_completion_target | 0.8 | configuration file checkpoint_segments | 32 | configuration file checkpoint_timeout | 10min | configuration file checkpoint_warning | 30s | configuration file client_encoding | UTF8 | client client_min_messages | warning | configuration file debug_pretty_print | off | configuration file debug_print_parse | off | configuration file debug_print_plan | off | configuration file debug_print_rewritten | off | configuration file default_statistics_target | 200 | configuration file effective_cache_size | 5870MB | configuration file fsync | on | configuration file full_page_writes | on | configuration file krb_server_keyfile | /usr/local/pgconf/PGpgsviltab | configuration file krb_srvname | POSTGRES | configuration file lc_messages | en_US.UTF-8 | configuration file lc_monetary | en_US.UTF-8 | configuration file lc_numeric | en_US.UTF-8 | configuration file lc_time | en_US.UTF-8 | configuration file listen_addresses | * | configuration file log_autovacuum_min_duration | 1s | configuration file log_checkpoints | on | configuration file log_connections | off | configuration file log_destination | stderr,syslog | configuration file log_directory | /dbms/logs | configuration file log_disconnections | off | configuration file log_duration | off | configuration file log_error_verbosity | default | configuration file log_filename | postgresql-%Y-%m-%d_%H%M%S.log | configuration file log_line_prefix | %t %r %u %d %x %c - | configuration file log_min_duration_statement | 6s | configuration file log_min_error_statement | error | configuration file log_min_messages | warning | configuration file log_rotation_age | 1d | configuration file log_rotation_size | 0 | configuration file log_statement | none | configuration file log_truncate_on_rotation | off | configuration file logging_collector | on | configuration file maintenance_work_mem | 300MB | configuration file max_connections | 100 | configuration file max_stack_depth | 2MB | environment variable port | 5432 | configuration file random_page_cost | 2 | configuration file shared_buffers | 1GB | configuration file superuser_reserved_connections | 3 | configuration file synchronous_commit | off | configuration file syslog_facility | local1 | configuration file syslog_ident | postgres | configuration file temp_buffers | 8MB | configuration file TimeZone | Europe/Rome | configuration file track_activities | on | configuration file track_counts | on | configuration file vacuum_cost_delay | 0 | configuration file vacuum_cost_limit | 200 | configuration file wal_buffers | 16MB | configuration file work_mem | 12MB | configuration file (64 rows) REMOTE SERVER: INFOLOG=# SELECT name, current_setting(name), source INFOLOG-# FROM pg_settings INFOLOG-# WHERE source NOT IN ('default', 'override'); name | current_setting | source --------------------------------+-----------------------------------------------+---------------------- application_name | psql | client archive_command | /usr/local/bin/pg_wal_archive_script.sh %p %f | configuration file archive_mode | on | configuration file archive_timeout | 0 | configuration file autovacuum | on | configuration file autovacuum_max_workers | 7 | configuration file autovacuum_naptime | 10min | configuration file autovacuum_vacuum_cost_delay | 20ms | configuration file autovacuum_vacuum_cost_limit | 200 | configuration file bytea_output | escape | configuration file checkpoint_completion_target | 0.8 | configuration file checkpoint_segments | 32 | configuration file checkpoint_timeout | 10min | configuration file client_encoding | UTF8 | client client_min_messages | warning | configuration file debug_pretty_print | off | configuration file debug_print_parse | off | configuration file debug_print_plan | off | configuration file debug_print_rewritten | off | configuration file default_statistics_target | 200 | configuration file effective_cache_size | 5870MB | configuration file fsync | on | configuration file full_page_writes | on | configuration file lc_messages | en_US.UTF-8 | configuration file lc_monetary | en_US.UTF-8 | configuration file lc_numeric | en_US.UTF-8 | configuration file lc_time | en_US.UTF-8 | configuration file listen_addresses | * | configuration file log_autovacuum_min_duration | 1s | configuration file log_checkpoints | on | configuration file log_connections | off | configuration file log_destination | stderr,syslog | configuration file log_directory | /dbms/logs | configuration file log_disconnections | off | configuration file log_duration | off | configuration file log_error_verbosity | default | configuration file log_filename | postgresql-%Y-%m-%d_%H%M%S.log | configuration file log_line_prefix | %t %r %u %d %x %c - | configuration file log_min_duration_statement | 6s | configuration file log_min_error_statement | error | configuration file log_min_messages | error | configuration file log_rotation_age | 1d | configuration file log_rotation_size | 0 | configuration file log_statement | none | configuration file log_truncate_on_rotation | off | configuration file logging_collector | on | configuration file maintenance_work_mem | 300MB | configuration file max_connections | 250 | configuration file max_stack_depth | 2MB | environment variable max_wal_senders | 5 | configuration file port | 5432 | configuration file random_page_cost | 2 | configuration file shared_buffers | 1GB | configuration file superuser_reserved_connections | 6 | configuration file synchronous_commit | off | configuration file syslog_facility | local4 | configuration file syslog_ident | postgres | configuration file temp_buffers | 8MB | configuration file track_activities | on | configuration file track_counts | on | configuration file vacuum_cost_delay | 0 | configuration file vacuum_cost_limit | 200 | configuration file wal_buffers | 16MB | configuration file wal_keep_segments | 10 | configuration file wal_level | hot_standby | configuration file work_mem | 12MB | configuration file (66 rows) OPERATING SYSTEM :
---------------------- LOCAL SERVER : Centos 6.4 uname -a Linux pg64test1.manord.com 2.6.32-358.14.1.el6.x86_64 #1 SMP Tue Jul 16 23:51:20 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux REMOTE SERVER : Centos 6.5 uname -a Linux pg64infolog.manord.com 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux |