PostgreSQL 성능 차이에 대해 질문이 있습니다.FreeBSD 8.2 가상 머신에서 두 개의 PostgreSQL 8.4 릴리스간에 큰 성능 차이가 있음
MAC OS X 시스템에서 django 웹 응용 프로그램을 개발 중이며 웹 응용 프로그램을 FreeBSD 서버에 배포해야합니다. 시스템 페이지에는 ajax로 제어되는 데이터 입력 필드가 있습니다. 이 필드에는 도시 이름을 입력 할 수 있으며 두 자 이상을 입력하면 시스템에서 데이터베이스의 도시를 찾기 시작하고 문자열 시작 부분에이 2 개 (또는 그 이상)의 문자를 따르는 도시의 드롭 다운을 표시합니다 .
이 모든 것들은 FreeBSD 서버에 배포하기 전에는 제대로 작동하는 것 같습니다. 처음 배포는 괜찮 았지만 두 번째 배포는 성능 차이가 큽니다.
이 테스트 결과의 목록은 다음과 같습니다
system1 proc: Intel Core 2 Duo 3.06 GHz, mem: 8GB. :
OS: OS X 10.6.8, 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011;
root:xnu-1504.15.3~1/RELEASE_I386 i386
DB: PostgreSQL 8.4.5 on i386-apple-darwin10.5.0, compiled by GCC i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664), 64-bit
Tests system1:
query parameter time in ms
01 'de%' 909
02 'de%' 886
03 'den%' 132
04 'den %' 115
05 'den h%' 115
06 'den ha%' 117
07 'den haa%' 95
08 'den haag%' 100
host: system1
guest: parallels virtual machine, proc: 2 cpu, mem: 1 GB.
system2
OS: 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Thu Feb 17 02:41:51 UTC 2011 [email protected]:/usr/obj/usr/src/sys/GENERIC amd64
DB: PostgreSQL 8.4.7 on amd64-portbld-freebsd8.2, compiled by GCC cc (GCC) 4.2.1 20070719 [FreeBSD], 64-bit
Tests system2:
query parameter time in ms
01 'de%' 1178
02 'de%' 857
03 'den%' 298
04 'den %' 233
05 'den h%' 134
06 'den ha%' 132
07 'den haa%' 132
08 'den haag%' 136
host: system1
guest: parallels virtual machine, proc: 2 cpu, mem: 1 GB.
system3
OS: 8.3-RELEASE FreeBSD 8.3-RELEASE #0: Mon Apr 9 21:23:18 UTC 2012 [email protected]:/usr/obj/usr/src/sys/GENERIC amd64
DB: PostgreSQL 8.4.11 on amd64-portbld-freebsd8.3, compiled by GCC cc (GCC) 4.2.2 20070831 prerelease [FreeBSD], 64-bit
Tests system3:
query parameter time in ms
01 'de%' 7096
02 'de%' 7012
03 'den%' 6228
04 'den %' 6237
05 'den h%' 6145
06 'den ha%' 5640
07 'den haa%' 5512
08 'den haag%' 5561
매개 변수는 방식으로 데이터가 아약스 응용 프로그램에 입력 모방. 이 결과는 응용 프로그램을 통하지 않고 pgAdmin3을 통해 데이터베이스에 직접 쿼리 한 결과입니다. 내가 관련성이 있다고 생각하지 않기 때문에 여기서 질문을하지 않았다. 데이터베이스는 동일하며 동일한 쿼리가 세 데이터베이스 인스턴스 모두에 사용됩니다.
이제 system1 : OS X 시스템, 베어 하드웨어 및 system2 : FreeBSD를 실행하는 가상 머신 간의 성능 차이를 이해할 수 있습니다.
내가 이해가 안가는 것은 system2와 system3 사이의 성능 차이가 두 VM이 동일한 호스트에서 실행되고 있다는 것입니다. 테스트는 개별적으로 실행되는 각 VM으로 수행되었습니다.
왜 이런 일이 일어날 수 있는지 실마리가 있습니까?
모든 시스템에 대해 먼저 VACUUM ANALYZE를 수행했습니다.
system1: PostgreSQL 8.4.5 on i386-apple-darwin10.5.0
"Limit (cost=3894.65..3894.70 rows=20 width=36) (actual time=1445.667..1445.671 rows=20 loops=1)"
" -> Sort (cost=3894.65..3903.99 rows=3736 width=36) (actual time=1445.666..1445.666 rows=20 loops=1)"
" Sort Key: public.geopoint_language.name_language,
" -> Seq Scan on geopoint (cost=0.00..618.94 rows=625 width=11) (actual time=0.018..6.277 rows=728 loops=1)"
" Filter: (((admin2_code)::text = ''::text) AND (country_id = 154))"
"Total runtime: 1446.377 ms"
system2: PostgreSQL 8.4.7 on amd64-portbld-freebsd8.2
"Limit (cost=3794.26..3794.31 rows=20 width=36) (actual time=64848.595..64848.903 rows=20 loops=1)"
" -> Sort (cost=3794.26..3800.41 rows=2460 width=36) (actual time=64848.583..64848.679 rows=20 loops=1)"
" Sort Key: public.geopoint_language.name_language, adm2_state_language.name_language, adm1_state_language.name_language"
" Sort Method: top-N heapsort Memory: 27kB"
" -> HashAggregate (cost=3704.20..3728.80 rows=2460 width=36) (actual time=64843.710..64846.020 rows=417 loops=1)"
" -> Append (cost=1055.08..3667.30 rows=2460 width=36) (actual time=1201.210..64839.849 rows=417 loops=1)"
" -> Hash Semi Join (cost=1055.08..1784.76 rows=163 width=48) (actual time=1201.199..64707.965 rows=362 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Merge Join (cost=1049.36..1776.47 rows=287 width=64) (actual time=1200.852..64703.138 rows=362 loops=1)"
" Merge Cond: (public.state.pstate_id = public.state.id)"
" -> Nested Loop (cost=843.55..3856.49 rows=470 width=72) (actual time=1199.848..64693.793 rows=362 loops=1)"
" -> Nested Loop (cost=843.55..2641.98 rows=4159 width=58) (actual time=39.390..64356.535 rows=13768 loops=1)"
" Join Filter: ((public.state.admin2_code)::text = (public.geopoint.admin2_code)::text)"
" -> Nested Loop Semi Join (cost=217.62..758.39 rows=8 width=51) (actual time=38.388..146.171 rows=862 loops=1)"
" -> Nested Loop (cost=217.62..754.28 rows=15 width=47) (actual time=38.361..124.606 rows=862 loops=1)"
" -> Nested Loop Semi Join (cost=217.62..616.50 rows=20 width=34) (actual time=38.332..87.939 rows=918 loops=1)"
" -> Merge Join (cost=217.62..606.79 rows=35 width=30) (actual time=38.300..58.248 rows=1066 loops=1)"
" Merge Cond: (adm1_state_language.state_id = public.state.pstate_id)"
" -> Index Scan using idx_state_language_1 on state_language adm1_state_language (cost=0.00..392.25 rows=7120 width=21) (actual time=0.019..16.666 rows=2826 loops=1)"
" Index Cond: (preferred = true)"
" -> Sort (cost=196.31..196.48 rows=68 width=9) (actual time=6.551..12.945 rows=1065 loops=1)"
" Sort Key: public.state.pstate_id"
" Sort Method: quicksort Memory: 45kB"
" -> Seq Scan on state (cost=0.00..194.24 rows=68 width=9) (actual time=0.019..3.928 rows=431 loops=1)"
" Filter: (((admin2_code)::text <> ''::text) AND (country_id = 154) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text))"
" -> Index Scan using pk_language_all on language (cost=0.00..0.27 rows=1 width=4) (actual time=0.011..0.011 rows=1 loops=1066)"
" Index Cond: (public.language.id = adm1_state_language.language_id)"
" Filter: public.language.enabled"
" -> Index Scan using idx_state_language_1 on state_language adm2_state_language (cost=0.00..6.87 rows=1 width=21) (actual time=0.011..0.018 rows=1 loops=918)"
" Index Cond: ((adm2_state_language.state_id = public.state.id) AND (adm2_state_language.language_id = adm1_state_language.language_id) AND (adm2_state_language.preferred = true))"
" -> Index Scan using pk_language_all on language (cost=0.00..0.27 rows=1 width=4) (actual time=0.008..0.008 rows=1 loops=862)"
" Index Cond: (public.language.id = adm1_state_language.language_id)"
" Filter: public.language.enabled"
" -> Materialize (cost=625.93..695.80 rows=6987 width=12) (actual time=0.005..36.752 rows=6884 loops=862)"
" -> Seq Scan on geopoint (cost=0.00..618.94 rows=6987 width=12) (actual time=0.015..45.945 rows=6884 loops=1)"
" Filter: (((admin2_code)::text <> ''::text) AND (country_id = 154))"
" -> Index Scan using idx_geopoint_language_3 on geopoint_language (cost=0.00..0.28 rows=1 width=18) (actual time=0.013..0.013 rows=0 loops=13768)"
" Index Cond: ((public.geopoint_language.geopoint_id = public.geopoint.id) AND (public.geopoint_language.language_id = adm1_state_language.language_id))"
" Filter: (public.geopoint_language.endonym AND ((public.geopoint_language.name_language)::text ~~* 'de%%'::text))"
" -> Sort (cost=205.72..206.42 rows=282 width=4) (actual time=0.984..3.008 rows=342 loops=1)"
" Sort Key: public.state.id"
" Sort Method: quicksort Memory: 25kB"
" -> Seq Scan on state (cost=0.00..194.24 rows=282 width=4) (actual time=0.427..0.850 rows=12 loops=1)"
" Filter: ((country_id = 154) AND ((admin2_code)::text = ''::text) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text))"
" -> Hash (cost=5.51..5.51 rows=17 width=4) (actual time=0.235..0.235 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.015..0.127 rows=17 loops=1)"
" Filter: enabled"
" -> Subquery Scan "*SELECT* 2" (cost=1844.22..1880.91 rows=2297 width=35) (actual time=125.544..127.175 rows=55 loops=1)"
" -> Merge Join (cost=1844.22..1857.94 rows=2297 width=35) (actual time=125.533..126.563 rows=55 loops=1)"
" Merge Cond: ((adm1_state_language.language_id = public.geopoint_language.language_id) AND ((public.state.admin1_code)::text = (public.geopoint.admin1_code)::text))"
" -> Sort (cost=392.00..392.29 rows=117 width=26) (actual time=82.529..82.647 rows=24 loops=1)"
" Sort Key: adm1_state_language.language_id, public.state.admin1_code"
" Sort Method: quicksort Memory: 26kB"
" -> Hash Join (cost=209.42..387.98 rows=117 width=26) (actual time=30.234..82.289 rows=25 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Hash Semi Join (cost=203.49..380.10 rows=206 width=22) (actual time=29.732..81.508 rows=25 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Hash Join (cost=197.77..371.13 rows=364 width=18) (actual time=29.442..80.926 rows=29 loops=1)"
" Hash Cond: (adm1_state_language.state_id = public.state.id)"
" -> Seq Scan on state_language adm1_state_language (cost=0.00..143.03 rows=7120 width=21) (actual time=0.008..39.728 rows=7120 loops=1)"
" Filter: preferred"
" -> Hash (cost=194.24..194.24 rows=282 width=5) (actual time=2.366..2.366 rows=12 loops=1)"
" -> Seq Scan on state (cost=0.00..194.24 rows=282 width=5) (actual time=1.185..2.271 rows=12 loops=1)"
" Filter: (((admin2_code)::text = ''::text) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text) AND (country_id = 154))"
" -> Hash (cost=5.51..5.51 rows=17 width=4) (actual time=0.224..0.224 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.008..0.118 rows=17 loops=1)"
" Filter: enabled"
" -> Hash (cost=5.72..5.72 rows=17 width=4) (actual time=0.445..0.445 rows=17 loops=1)"
" -> HashAggregate (cost=5.55..5.72 rows=17 width=4) (actual time=0.233..0.323 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.010..0.125 rows=17 loops=1)"
" Filter: enabled"
" -> Sort (cost=1452.22..1453.21 rows=396 width=25) (actual time=42.856..43.140 rows=55 loops=1)"
" Sort Key: public.geopoint_language.language_id, public.geopoint.admin1_code"
" Sort Method: quicksort Memory: 29kB"
" -> Hash Join (cost=626.75..1435.14 rows=396 width=25) (actual time=23.266..42.430 rows=55 loops=1)"
" Hash Cond: (public.geopoint_language.geopoint_id = public.geopoint.id)"
" -> Seq Scan on geopoint_language (cost=0.00..802.94 rows=396 width=18) (actual time=3.081..25.949 rows=515 loops=1)"
" Filter: (endonym AND ((name_language)::text ~~* 'de %%'::text))"
" -> Hash (cost=618.94..618.94 rows=625 width=11) (actual time=13.194..13.194 rows=728 loops=1)"
" -> Seq Scan on geopoint (cost=0.00..618.94 rows=625 width=11) (actual time=0.015..8.770 rows=728 loops=1)"
" Filter: (((admin2_code)::text = ''::text) AND (country_id = 154))"
"Total runtime: 64850.211 ms"
system3: PostgreSQL 8.4.11 on amd64-portbld-freebsd8.3
"Limit (cost=2715.73..2715.78 rows=20 width=35) (actual time=28363.433..28363.721 rows=20 loops=1)"
" -> Sort (cost=2715.73..2716.02 rows=113 width=35) (actual time=28363.421..28363.516 rows=20 loops=1)"
" Sort Key: public.geopoint_language.name_language, adm2_state_language.name_language, adm1_state_language.name_language"
" Sort Method: top-N heapsort Memory: 27kB"
" -> HashAggregate (cost=2711.60..2712.73 rows=113 width=35) (actual time=28358.553..28360.849 rows=419 loops=1)"
" -> Append (cost=571.63..2709.90 rows=113 width=35) (actual time=349.502..28354.791 rows=419 loops=1)"
" -> Hash Semi Join (cost=571.63..884.24 rows=3 width=48) (actual time=349.492..28233.388 rows=362 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Nested Loop (cost=565.91..878.47 rows=5 width=64) (actual time=349.172..28228.620 rows=362 loops=1)"
" Join Filter: ((public.state.admin2_code)::text = (public.geopoint.admin2_code)::text)"
" -> Merge Join (cost=565.91..811.16 rows=25 width=61) (actual time=278.147..20849.826 rows=292218 loops=1)"
" Merge Cond: (public.state.pstate_id = adm1_state_language.state_id)"
" Join Filter: (adm1_state_language.language_id = adm2_state_language.language_id)"
" -> Nested Loop (cost=233.49..1199.63 rows=277 width=44) (actual time=12.014..10783.473 rows=292218 loops=1)"
" -> Nested Loop (cost=233.49..725.31 rows=1 width=26) (actual time=7.617..42.736 rows=862 loops=1)"
" -> Merge Join (cost=233.49..720.62 rows=1 width=13) (actual time=7.585..16.639 rows=431 loops=1)"
" Merge Cond: (public.state.id = public.state.pstate_id)"
" -> Index Scan using pk_state on state (cost=0.00..523.51 rows=282 width=4) (actual time=1.000..2.268 rows=12 loops=1)"
" Filter: ((country_id = 154) AND ((admin2_code)::text = ''::text) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text))"
" -> Sort (cost=196.31..196.48 rows=68 width=9) (actual time=6.566..9.020 rows=431 loops=1)"
" Sort Key: public.state.pstate_id"
" Sort Method: quicksort Memory: 45kB"
" -> Seq Scan on state (cost=0.00..194.24 rows=68 width=9) (actual time=0.015..3.942 rows=431 loops=1)"
" Filter: (((admin2_code)::text <> ''::text) AND (country_id = 154) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text))"
" -> Index Scan using idx_state_language_1 on state_language adm2_state_language (cost=0.00..4.68 rows=1 width=21) (actual time=0.012..0.026 rows=2 loops=431)"
" Index Cond: ((adm2_state_language.state_id = public.state.id) AND (adm2_state_language.preferred = true))"
" -> Index Scan using idx_geopoint_language_3 on geopoint_language (cost=0.00..471.76 rows=205 width=18) (actual time=2.051..8.854 rows=339 loops=862)"
" Index Cond: (public.geopoint_language.language_id = adm2_state_language.language_id)"
" Filter: (public.geopoint_language.endonym AND ((public.geopoint_language.name_language)::text ~~* 'de%%'::text))"
" -> Sort (cost=331.82..337.54 rows=2286 width=29) (actual time=237.631..3511.098 rows=625149 loops=1)"
" Sort Key: adm1_state_language.state_id"
" Sort Method: quicksort Memory: 746kB"
" -> Hash Join (cost=11.87..204.28 rows=2286 width=29) (actual time=0.996..192.413 rows=7023 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Hash Join (cost=5.94..180.49 rows=4035 width=25) (actual time=0.514..116.195 rows=7023 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Seq Scan on state_language adm1_state_language (cost=0.00..143.03 rows=7120 width=21) (actual time=0.007..38.638 rows=7120 loops=1)"
" Filter: preferred"
" -> Hash (cost=5.72..5.72 rows=17 width=4) (actual time=0.452..0.452 rows=17 loops=1)"
" -> HashAggregate (cost=5.55..5.72 rows=17 width=4) (actual time=0.260..0.350 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.008..0.136 rows=17 loops=1)"
" Filter: enabled"
" -> Hash (cost=5.72..5.72 rows=17 width=4) (actual time=0.425..0.425 rows=17 loops=1)"
" -> HashAggregate (cost=5.55..5.72 rows=17 width=4) (actual time=0.231..0.322 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.010..0.118 rows=17 loops=1)"
" Filter: enabled"
" -> Index Scan using pk_city on geopoint (cost=0.00..2.68 rows=1 width=12) (actual time=0.008..0.011 rows=1 loops=292218)"
" Index Cond: (public.geopoint.id = public.geopoint_language.geopoint_id)"
" Filter: (((public.geopoint.admin2_code)::text <> ''::text) AND (public.geopoint.country_id = 154))"
" -> Hash (cost=5.51..5.51 rows=17 width=4) (actual time=0.230..0.230 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.014..0.124 rows=17 loops=1)"
" Filter: enabled"
" -> Subquery Scan "*SELECT* 2" (cost=1014.04..1825.63 rows=110 width=35) (actual time=100.899..116.913 rows=57 loops=1)"
" -> Hash Join (cost=1014.04..1824.53 rows=110 width=35) (actual time=100.889..116.323 rows=57 loops=1)"
" Hash Cond: (((public.geopoint.admin1_code)::text = (public.state.admin1_code)::text) AND (public.geopoint_language.language_id = adm1_state_language.language_id))"
" -> Hash Join (cost=626.75..1432.19 rows=19 width=25) (actual time=19.280..34.017 rows=57 loops=1)"
" Hash Cond: (public.geopoint_language.geopoint_id = public.geopoint.id)"
" -> Seq Scan on geopoint_language (cost=0.00..802.94 rows=616 width=18) (actual time=1.942..16.204 rows=720 loops=1)"
" Filter: (endonym AND ((name_language)::text ~~* 'de%%'::text))"
" -> Hash (cost=618.94..618.94 rows=625 width=11) (actual time=13.437..13.437 rows=728 loops=1)"
" -> Seq Scan on geopoint (cost=0.00..618.94 rows=625 width=11) (actual time=0.012..8.923 rows=728 loops=1)"
" Filter: (((admin2_code)::text = ''::text) AND (country_id = 154))"
" -> Hash (cost=385.53..385.53 rows=117 width=26) (actual time=81.568..81.568 rows=25 loops=1)"
" -> Hash Join (cost=209.64..385.53 rows=117 width=26) (actual time=29.986..81.410 rows=25 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Hash Join (cost=203.70..378.69 rows=206 width=22) (actual time=29.457..80.612 rows=25 loops=1)"
" Hash Cond: (adm1_state_language.language_id = public.language.id)"
" -> Hash Join (cost=197.77..371.13 rows=364 width=18) (actual time=29.011..79.869 rows=29 loops=1)"
" Hash Cond: (adm1_state_language.state_id = public.state.id)"
" -> Seq Scan on state_language adm1_state_language (cost=0.00..143.03 rows=7120 width=21) (actual time=0.008..38.849 rows=7120 loops=1)"
" Filter: preferred"
" -> Hash (cost=194.24..194.24 rows=282 width=5) (actual time=2.245..2.245 rows=12 loops=1)"
" -> Seq Scan on state (cost=0.00..194.24 rows=282 width=5) (actual time=1.139..2.167 rows=12 loops=1)"
" Filter: (((admin2_code)::text = ''::text) AND ((admin3_code)::text = ''::text) AND ((admin4_code)::text = ''::text) AND (country_id = 154))"
" -> Hash (cost=5.72..5.72 rows=17 width=4) (actual time=0.423..0.423 rows=17 loops=1)"
" -> HashAggregate (cost=5.55..5.72 rows=17 width=4) (actual time=0.226..0.317 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.008..0.119 rows=17 loops=1)"
" Filter: enabled"
" -> Hash (cost=5.72..5.72 rows=17 width=4) (actual time=0.449..0.449 rows=17 loops=1)"
" -> HashAggregate (cost=5.55..5.72 rows=17 width=4) (actual time=0.254..0.344 rows=17 loops=1)"
" -> Seq Scan on language (cost=0.00..5.51 rows=17 width=4) (actual time=0.010..0.119 rows=17 loops=1)"
" Filter: enabled"
"Total runtime: 28366.784 ms"
시스템 2 및 시스템 3에 표시된 시간은 나에게 이해가되지 않습니다.
여러 가지 일 수 있지만 먼저 캐시 및 다른 저수준 디스크 구성이 동일한 지 확인하십시오. 큰 성능 차이는 거의 항상 디스크 IO의 차이입니다. – Gene
EXPLAIN ANALYZE를 사용하여 쿼리를 수동으로 실행하면 시간이 어디로 가고 계획이 동일한 지 확인할 수 있습니다. 통계가 최신인지 확인하려면 먼저 VACUUM ANALYZE를 실행해야합니다. 두 가지 모두에 대한 Explain 분석 결과를 질문에 추가하십시오. DB의 크기는 얼마입니까? 그다지 많지 않으면 1GB 디스크 IO가 문제가되지 않을 것입니다. 몇 번 실행하면 모든 것이 OS 캐시에 저장됩니다. – Eelke
두 시스템에서 {shared_buffers, effective_cache_size, work_mem, random_page_cost}의 구성 값을 확인하십시오. (공유 버퍼 설정 * 너무 높음 * VM, IIRC에 부정적인 영향을 줄 수 있음) – wildplasser