開始
數據量很小的時候,我們可以看到,seq scan 比 index scan 更加有效。那是因為 index scan 至少要發生兩次I/O,一次是 讀取索引塊, 一次是讀取數據塊。當index 很大的時候,情況可能會更加復雜。
postgres=# select a.relpages, a.reltuples, a.relfilenode,a.reltype,b.typname from pg_class a, pg_type b where a.relname like 'gaotab%' and a.reltype=b.oid; relpages | reltuples | relfilenode | reltype | typname ----------+-----------+-------------+---------+--------- 1 | 100 | 16396 | 16386 | gaotab
數據量為 100條記錄。
預估成本:
postgres=# set session enable_seqscan=false; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN --------------------------------------------------------------------- Index Scan using idx_id on gaotab (cost=0.00..8.27 rows=1 width=5) Index Cond: (id = 50) (2 rows)
postgres=# set session enable_seqscan=true; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN ------------------------------------------------------ Seq Scan on gaotab (cost=0.00..2.25 rows=1 width=5) Filter: (id = 50) (2 rows)
實際執行:
postgres=# set session enable_seqscan=false; SET postgres=# explain analyze select name from gaotab where id=50; QUERY PLAN -------------------------------------------------------------------------------- ------------------------------- Index Scan using idx_id on gaotab (cost=0.00..8.27 rows=1 width=5) (actual tim e=0.112..0.113 rows=1 loops=1) Index Cond: (id = 50) Total runtime: 0.133 ms (3 rows)
postgres=# set session enable_seqscan=true; SET postgres=# explain analyze select name from gaotab where id=50; QUERY PLAN -------------------------------------------------------------------------------- ---------------- Seq Scan on gaotab (cost=0.00..2.25 rows=1 width=5) (actual time=0.014..0.018 rows=1 loops=1) Filter: (id = 50) Rows Removed by Filter: 99 Total runtime: 0.034 ms (4 rows)
等到數據量大的時候,就是截然不同了。
數據為1000條記錄時,通過查詢可以看到,已經跨越了7個page:
postgres=# analyze; ANALYZE postgres=# select a.relpages, a.reltuples, a.relfilenode,a.reltype,b.typname from pg_class a, pg_type b where a.relname like 'gaotab%' and a.reltype=b.oid; relpages | reltuples | relfilenode | reltype | typname ----------+-----------+-------------+---------+--------- 7 | 1000 | 16396 | 16386 | gaotab (1 row) postgres=#
再次預估成本,此時seq scan 已經開始變得不划算了:
postgres=# set session enable_seqscan=false; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN --------------------------------------------------------------------- Index Scan using idx_id on gaotab (cost=0.00..8.27 rows=1 width=6) Index Cond: (id = 50) (2 rows) postgres=# set session enable_seqscan=true; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN --------------------------------------------------------------------- Index Scan using idx_id on gaotab (cost=0.00..8.27 rows=1 width=6) Index Cond: (id = 50) (2 rows) postgres=# set session enable_indexscan=false; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN --------------------------------------------------------------------- Bitmap Heap Scan on gaotab (cost=4.26..8.27 rows=1 width=6) Recheck Cond: (id = 50) -> Bitmap Index Scan on idx_id (cost=0.00..4.26 rows=1 width=0) Index Cond: (id = 50) (4 rows) postgres=# set session enable_bitmapscan=false; SET postgres=# explain select name from gaotab where id=50; QUERY PLAN ------------------------------------------------------- Seq Scan on gaotab (cost=0.00..19.50 rows=1 width=6) Filter: (id = 50) (2 rows) postgres=#
實際執行
postgres=# set session enable_seqscan=false; SET postgres=# explain analyze select name from gaotab where id=50; QUERY PLAN ------------------------------------------------------------------------------------------------------------ ----------------------- Index Scan using idx_id on gaotab (cost=10000000000.00..10000000008.27 rows=1 width=6) (actual time=0.020. .0.022 rows=1 loops=1) Index Cond: (id = 50) Total runtime: 0.051 ms (3 rows) postgres=# set session enable_seqscan=true; SET postgres=# set session enable_indexscan=false; SET postgres=# set session enable_bitmapscan=false; SET postgres=# explain analyze select name from gaotab where id=50; QUERY PLAN ------------------------------------------------------------------------------------------------- Seq Scan on gaotab (cost=0.00..19.50 rows=1 width=6) (actual time=0.015..0.095 rows=1 loops=1) Filter: (id = 50) Rows Removed by Filter: 999 Total runtime: 0.109 ms (4 rows) postgres=#
[作者:技術者高健@博客園 mail: luckyjackgao@gmail.com ]
結束