
> sudo service postgresql-9.3 stop > sudo sync > sudo su - # echo 3 > /proc/sys/vm/drop_caches # exit > sudo service postgresql-9.3 start  EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM foo; QUERY PLAN
- Seq Scan on foo (cost = 0.00..18334.10 rows = 1000010 width = 37) (actual time = 0.525..734.754 rows = 1000010 loops = 1)
Buffers: shared read = 8334
Total runtime: 1253.177 ms
(3 rows)
Buffers: shared read - the number of blocks read from the disk. EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM foo; QUERY PLAN
- Seq Scan on foo (cost = 0.00..18334.10 rows = 1000010 width = 37) (actual time = 0.173..693.000 rows = 1000010 loops = 1)
Buffers: shared hit = 32 read = 8302
Total runtime: 1208.433 ms
(3 rows)
Buffers: shared hit - the number of blocks read from the PostgreSQL cache.Total runtime value.shared_buffers constant in the postgresql.conf file. EXPLAIN SELECT * FROM foo WHERE c1 > 500; QUERY PLAN
- Seq Scan on foo (cost = 0.00..20834.12 rows = 999522 width = 37)
Filter: (c1> 500)
(2 rows)
Seq Scan ). Each record is compared with the condition c1 > 500 . If the condition is met, the entry is entered into the result. Otherwise, it is discarded. Filter means exactly this behavior.cost , which is logical, has increased.rows - decreased.cost takes just such a value, and how the expected number of rows is calculated. CREATE INDEX ON foo(c1); EXPLAIN SELECT * FROM foo WHERE c1 > 500; QUERY PLAN
- Seq Scan on foo (cost = 0.00..20834.12 rows = 999519 width = 37)
Filter: (c1> 500)
(2 rows)
 EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c1 > 500; QUERY PLAN
- Seq Scan on foo (cost = 0.00..20834.12 rows = 999519 width = 37) (actual time = 0.572..848.895 rows = 999500 loops = 1)
Filter: (c1> 500)
Rows Removed by Filter: 510
Total runtime: 1330.788 ms
(4 rows)
 SET enable_seqscan TO off; EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c1 > 500; QUERY PLAN
- Index Scan using foo_c1_idx on foo (cost = 0.42..34623.01 rows = 999519 width = 37) (actual time = 0.178..1018.045 rows = 999500 loops = 1)
Index Cond: (c1> 500)
Total runtime: 1434.429 ms
(3 rows)
Index Scan , Index Cond instead of Filter - the index foo_c1_idx is used.cost and run time of the query. Planner is not stupid! SET enable_seqscan TO on;  EXPLAIN SELECT * FROM foo WHERE c1 < 500; QUERY PLAN
- Index Scan using foo_c1_idx on foo (cost = 0.42..25.78 rows = 491 width = 37)
Index Cond: (c1 <500)
(2 rows)
 EXPLAIN SELECT * FROM foo WHERE c1 < 500 AND c2 LIKE 'abcd%'; QUERY PLAN
- Index Scan using foo_c1_idx on foo (cost = 0.42..27.00 rows = 1 width = 37)
Index Cond: (c1 <500)
Filter: (c2 ~ abcd% ':: text)
(3 rows)
foo_c1_idx for the condition c1 < 500 . For c2 ~~ 'abcd%'::text , a filter is used. EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c2 LIKE 'abcd%'; QUERY PLAN
- Seq Scan on foo (cost = 0.00..20834.12 rows = 100 width = 37) (actual time = 14.497 ..412.030 rows = 10 loops = 1)
Filter: (c2 ~ abcd% ':: text)
Rows Removed by Filter: 1000000
Total runtime: 412.120 ms
(4 rows)
Seq Scan .c2 : CREATE INDEX ON foo(c2); EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c2 LIKE 'abcd%'; QUERY PLAN
- Seq Scan on foo (cost = 0.00..20834.12 rows = 100 width = 37) (actual time = 20.992..424.946 rows = 10 loops = 1)
Filter: (c2 ~ abcd% ':: text)
Rows Removed by Filter: 1000000
Total runtime: 425.039 ms
(4 rows)
Seq Scan ? The index is not used because I have a base for text fields using the UTF-8 format.text_pattern_ops operator text_pattern_ops : CREATE INDEX ON foo(c2 text_pattern_ops); EXPLAIN SELECT * FROM foo WHERE c2 LIKE 'abcd%'; QUERY PLAN
- Bitmap Heap Scan on foo (cost = 4.58..55.20 rows = 100 width = 37)
Filter: (c2 ~ abcd% ':: text)
-> Bitmap Index Scan on foo_c2_idx1 (cost = 0.00 ..4.55 rows = 13 width = 0)
Index Cond: ((c2 ~> = ~ 'abcd' :: text) AND (c2 ~ <~ 'abce' :: text))
(4 rows)
Bitmap Index Scan - the foo_c2_idx1 index is used to determine the records we need, and then PostgreSQL crawls into the table itself: ( Bitmap Heap Scan ) - to make sure that these records actually exist. This behavior is related to PostgreSQL versioning. EXPLAIN SELECT c1 FROM foo WHERE c1 < 500; QUERY PLAN
- Index Only Scan using foo_c1_idx on foo (cost = 0.42..25.78 rows = 491 width = 4)
Index Cond: (c1 <500)
(2 rows)
Index Only Scan runs faster than Index Scan due to the fact that you do not need to read the entire table row: width=4 .Source: https://habr.com/ru/post/203386/
All Articles