> 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