프로덕션 환경에서는 느리지 만 개발 컴퓨터에서는 빠르게 쿼리를 디버깅하려고합니다. 내 dev에 상자는 불과 며칠 오래된 prod 데이터베이스의 스냅 샷을 가지고 있으므로 두 DB의 내용은 거의 같습니다.Postgresql 쿼리 계획 불일치
쿼리는 다음과 같습니다
select count(*) from big_table where search_column in ('something')
참고 :
big_table
약 35M 행이 snapshot materialized view하고 매일search_column
갱신 B-tree 인덱스를 가지고있다.explain analyze
의- 자극이
- 디바이스가 OS 9.0 우분투 9.1 인 X
쿼리 계획
결과 :
자극 :
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=1119843.20..1119843.21 rows=1 width=0) (actual time=467388.276..467388.278 rows=1 loops=1)
-> Bitmap Heap Scan on big_table (cost=10432.55..1118804.45 rows=415497 width=0) (actual time=116891.126..466949.331 rows=210053 loops=1)
Recheck Cond: ((search_column)::text = 'something'::text)
-> Bitmap Index Scan on big_table_search_column_index (cost=0.00..10328.68 rows=415497 width=0) (actual time=8467.901..8467.901 rows=337164 loops=1)
Index Cond: ((search_column)::text = 'something'::text)
Total runtime: 467389.534 ms
(6 rows)
dev :
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=524011.38..524011.39 rows=1 width=0) (actual time=209.852..209.852 rows=1 loops=1)
-> Bitmap Heap Scan on big_table (cost=5131.43..523531.22 rows=192064 width=0) (actual time=33.792..194.730 rows=209551 loops=1)
Recheck Cond: ((search_column)::text = 'something'::text)
-> Bitmap Index Scan on big_table_search_column_index (cost=0.00..5083.42 rows=192064 width=0) (actual time=27.568..27.568 rows=209551 loops=1)
Index Cond: ((search_column)::text = 'something'::text)
Total runtime: 209.938 ms
(6 rows)
및 자극 및 디바이스에 대한 두 개의 쿼리의 실제 결과는 각각 210,053 및 209,551의 행이다.
두 계획의 구조는 동일하지만 각 DB의 테이블에 대략 동일한 수의 행이있는 경우 위의 비용 차이를 설명 할 수 있습니까?
자극 :
current_database | schemaname | tablename | tbloat | wastedbytes | iname | ibloat | wastedibytes
------------------+------------+---------------------------------+--------+-------------+---------------------------------------------------------------+--------+--------------
my_db | public | big_table | 1.6 | 7965433856 | big_table_search_column_index | 0.1 | 0
블로 @의 BMA의 제안에
, 여기에 자극 및 디바이스 및 관련 테이블/인덱스에 대한 "팽창"쿼리의 결과는 dev :
current_database | schemaname | tablename | tbloat | wastedbytes | iname | ibloat | wastedibytes
------------------+------------+---------------------------------+--------+-------------+---------------------------------------------------------------+--------+--------------
my_db | public | big_table | 0.8 | 0 | big_table_search_column_index | 0.1 | 0
바일 라, 여기에 차이가 있습니다.
나는 vacuum analyze big_table;
을 실행했지만 카운트 쿼리의 실행 시간과 큰 차이가없는 것처럼 보입니다.
구성
SELECT name, current_setting(name), source FROM pg_settings WHERE source NOT IN ('default', 'override');
의
결과 BMA에 의해 제안 :
자극 :
name | current_setting | source
----------------------------+----------------------------------+----------------------
application_name | psql | client
DateStyle | ISO, MDY | configuration file
default_text_search_config | pg_catalog.english | configuration file
effective_cache_size | 6GB | configuration file
external_pid_file | /var/run/postgresql/9.1-main.pid | configuration file
listen_addresses | * | configuration file
log_line_prefix | %t | configuration file
log_timezone | localtime | environment variable
max_connections | 100 | configuration file
max_stack_depth | 2MB | environment variable
port | 5432 | configuration file
shared_buffers | 2GB | configuration file
ssl | on | configuration file
TimeZone | localtime | environment variable
unix_socket_directory | /var/run/postgresql | configuration file
(15 rows)
dev에 :
name | current_setting | source
----------------------------+-------------------------+----------------------
application_name | psql | client
DateStyle | ISO, MDY | configuration file
default_text_search_config | pg_catalog.english | configuration file
effective_cache_size | 4GB | configuration file
lc_messages | en_US | configuration file
lc_monetary | en_US | configuration file
lc_numeric | en_US | configuration file
lc_time | en_US | configuration file
listen_addresses | * | configuration file
log_destination | syslog | configuration file
log_directory | ../var | configuration file
log_filename | postgresql-%Y-%m-%d.log | configuration file
log_line_prefix | %t | configuration file
log_statement | all | configuration file
log_timezone | Australia/Hobart | command line
logging_collector | on | configuration file
maintenance_work_mem | 512MB | configuration file
max_connections | 50 | configuration file
max_stack_depth | 2MB | environment variable
shared_buffers | 2GB | configuration file
ssl | off | configuration file
synchronous_commit | off | configuration file
TimeZone | Australia/Hobart | command line
timezone_abbreviations | Default | command line
work_mem | 100MB | configuration file
(25 rows)
테스트 전에 프로덕션 db에서 "ANALYZE"를 실행 했습니까? 또한 dev 버전은 최적 상태에있을 가능성이 높습니다. 데이터는 디스크에서 연속적입니다. 여기서 생산 (정상적인 UPDATE/DELETE 사용을 가정 할 때)은 그렇지 않습니다. 또한 : bloat : http://wiki.postgresql.org/wiki/Show_database_bloat를 확인하고 서버마다 다른 구성 설정이 있는지 표시하십시오. SELECT 이름, current_setting (이름), 소스 발신자 번호 pg_settings 소스 없음 IN ('default', 'override'); – bma
다시 분석 : DB에 대해 자동 실행 프로세스가 실행 중입니다 - 분석 실행 중인지 어떻게 확인합니까? –
Re UPDATE/DELETE - 테이블이 구체화 된 뷰에 대한 추가 참고 사항을 참조하십시오. - 이것은 연속성이라는 측면에서 볼 때 두 가지 환경이 상당히 비슷하다는 것을 의미한다고 가정합니다. –