SlideShare a Scribd company logo
© 2019 Percona
Termini PostgreSQL di Deep Dee Intu
© 2019 Percona
Ibrar Ahmed
Deep Dive Into PostgreSQL Indexes
Learn PostgreSQL index
Senior Database Architect - Percona LLC
October – 16, 2019
© 2019 Percona
Heap vs Index
© 2019 Percona
• Rows / Tuples stored in a table
• Every table in PostgreSQL has physical disk file(s)
postgres=# CREATE TABLE foo(id int, name text);
postgres=# SELECT relfilenode FROM pg_class WHERE relname LIKE 'foo’;
relfilenode
-------------
16384
• The physical files on disk can be seen in the PostgreSQL $PGDATA directory.
$ ls -lrt $PGDATA/base/13680/16384
-rw------- 1 vagrant vagrant 0 Apr 29 11:48 $PGDATA/base/13680/16384
Tables (Heap)
“Tuple” and “Rows” are synonym
$PGDATA is Data Directory
“pg_class” is system table to contain table information“Relfilenode” is table file name of that table
“16384” is table filename
• Tuple stored in a table does not have any order
© 2019 Percona
EXPLAIN SELECT name FROM bar;
QUERY PLAN
----------------------------------------------------------------------------
Seq Scan on bar (cost=0.00..163693.05 rows=9999905 width=11
EXPLAIN SELECT name FROM bar WHERE id = 5432;
QUERY PLAN
----------------------------------------------------------------------------
Gather (cost=1000.00..116776.94 rows=1 width=11)
Workers Planned: 2
-> Parallel Seq Scan on bar (cost=0.00..115776.84 rows=1 width=11)
Filter: (id = 5432)
Tables (Heap)
• Select whole table, must be a sequential scan.
• Select table’s rows where id is 5432, it should not be a sequential scan.
Make sense?
Why?
© 2019 Percona
Selecting Data from HEAP
Page 0/N
Page 1/N
Page 2/N
Page N/N
Tuple - 1
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - n
CREATE TABLE foo(id INTEGER, name TEXT);
INSERT INTO foo VALUES(1, 'Alex');
INSERT INTO foo VALUES(2, 'Bob');
SELECT ctid, * FROM foo;
ctid | id | name
-------+----+------
(0,1) | 1 | Alex
(0,2) | 2 | Bob
(2 rows)
H
E
A
P
• How to select the data from the HEAP?
• Need to scan each and every page and look for the
tuple in the page
Cost?
© 2019 Percona
PostgreSQL Indexes
https://www.postgresql.org/docs/current/indexes.html
7
© 2019 Percona
postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432;
QUERY PLAN
----------------------------------------------------------------------------
Bitmap Heap Scan on bar (cost=939.93..64313.02 rows=50000 width=32)
Recheck Cond: (id = 5432)
-> Bitmap Index Scan on bar_idx (cost=0.00..927.43 rows=50000 width=0)
Index Cond: (id = 5432)
postgres=# CREATE INDEX bar_idx ON bar(id);
postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432;
QUERY PLAN
----------------------------------------------------------------------------
Seq Scan on bar (cost=0.00..159235.00 rows=38216 width=32)
Filter: (id = 5432)
Why Index?
• Indexes are entry points for tables
• Index used to locate the tuples in the table
• The sole reason to have an index is performance
• Index is stored separately from the table’s main storage (PostgreSQL Heap)
• More storage required to store the index along with original table
64313/159235 * 100 = 40%
Cost of the query
© 2019 Percona
postgres=# CREATE INDEX idx_btree ON bar(id);
postgres=# SELECT relfilenode FROM pg_class WHERE relname LIKE ‘idx_btree’;
relfilenode
-------------
16425
Index
Physical file name of the index
PostgreSQL’s Catalog for relations/index
The physical file on disk can be seen in the PostgreSQL $PGDATA directory.
$ ls -lrt $PGDATA/13680/16425
-rw-------1 vagrant vagrant 1073741824 Apr 29 13:05 $PGDATA/base/13680/16425
• PostgreSQL standard way to create a index
(https://www.postgresql.org/docs/current/sql-createindex.html)
• PostgreSQL index has its own file on disk.
© 2019 Percona
postgres=# CREATE INDEX bar_idx ON bar(id);
Creating Index 1/2
”bar” is a table and ”id” is column
postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432;
QUERY PLAN
----------------------------------------------------------------------
Bitmap Heap Scan on bar (cost=939.93..64313.02 rows=50000 width=32)
Recheck Cond: (id = 5432)
-> Bitmap Index Scan on bar_idx (cost=0.00..927.43 rows=50000 width=0)
Index Cond: (id = 5432)
• Index based on single column of the table
© 2019 Percona
CREATE INDEX CONCURRENTLY idx_btree ON bar USING BTREE(id);
CREATE INDEX
Time: 23025.372 ms (00:23.025)
CREATE INDEX idx_btree ON bar USING BTREE(id);
CREATE INDEX
Time: 12303.172 ms (00:12.303)
Creating Index 2/2
• PostgreSQL locks the table when creating index
• CONCURRENTLY option creates the index without locking the table
© 2019 Percona
Expression Index 1/2
CREATE INDEX idx_exp ON bar (lower(name));
EXPLAIN SELECT * FROM bar WHERE lower(name) LIKE 'Text1';
QUERY PLAN
-------------------------------------------------------------
Seq Scan on bar (cost=0.00..213694.00 rows=50000 width=40)
Filter: (lower((name)::text) ~~ 'Text1'::text)
EXPLAIN SELECT * FROM bar WHERE lower(name) LIKE 'Text1';
QUERY PLAN
-----------------------------------------------------------------------------
Bitmap Heap Scan on bar (cost=1159.93..64658.02 rows=50000 width=40)
Filter: (lower((name)::text) ~~ 'Text1'::text)
-> Bitmap Index Scan on idx_exp (cost=0.00..1147.43 rows=50000 width=0)
Index Cond: (lower((name)::text) = 'Text1'::text)
© 2019 Percona
Expression Index 2/2
postgres=# EXPLAIN SELECT * FROM bar WHERE (dt + (INTERVAL '2 days')) < now();
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on bar (cost=62449.77..184477.10 rows=3333333 width=40)
Recheck Cond: ((dt + '2 days'::interval) < now())
-> Bitmap Index Scan on idx_math_exp (cost=0.00..61616.43 rows=3333333 width=0)
Index Cond: ((dt + '2 days'::interval) < now())
postgres=# CREATE INDEX idx_math_exp ON bar((dt + (INTERVAL '2 days')));
postgres=# EXPLAIN SELECT * FROM bar WHERE (dt + (INTERVAL '2 days')) < now();
QUERY PLAN
---------------------------------------------------------------
Seq Scan on bar (cost=0.00..238694.00 rows=3333333 width=40)
Filter: ((dt + '2 days'::interval) < now())
© 2019 Percona
Partial Index
14
CREATE INDEX idx_part ON bar(id) where id < 1000;
EXPLAIN SELECT * FROM bar
WHERE id < 1000
AND name LIKE 'text1000’;
QUERY PLAN
-----------------------------------------------------------------------
Bitmap Heap Scan on bar (cost=199.44..113893.44 rows=16667 width=40)
Recheck Cond: (id < 1000)
Filter: ((name)::text ~~ 'text1000'::text)
-> Bitmap Index Scan on idx_part (cost=0.00..195.28 rows=3333333
width=0)
Index Cond: (id < 1000)
SELECT pg_size_pretty(pg_total_relation_size('idx_part'));
pg_size_pretty
----------------
240 kB
(1 row)
CREATE INDEX idx_full ON bar(id);
EXPLAIN SELECT * FROM bar
WHERE id < 1000
AND name LIKE 'text1000’;
QUERY PLAN
------------------------------------------------------------------------
--
Bitmap Heap Scan on bar (cost=61568.60..175262.59 rows=16667 width=40)
Recheck Cond: (id < 1000)
Filter: ((name)::text ~~ 'text1000'::text)
-> Bitmap Index Scan on idx_full (cost=0.00..61564.43 rows=3333333
width=0)
Index Cond: (id < 1000)
SELECT pg_size_pretty(pg_total_relation_size('idx_full'));
pg_size_pretty
----------------
214 MB
(1 row)
Look at the size of the index
Why create full index if we don’t
need that.
Index Partial Index
Index where id < 1000 only
Q: What will happen when we query where id >1000?
A: Answer is simple, this index won’t selected.
© 2019 Percona
Index Types
https://www.postgresql.org/docs/current/indexes-types.html
© 2019 Percona
B-Tree Index 1/2
16
CREATE INDEX idx_btree ON foo USING BTREE (name);
• What is a B-Tree index?
• Supported Operators
• Less than <
• Less than equal to <=
• Equal =
• Greater than equal to >=
• Greater than >
Wikipedia: (https://en.wikipedia.org/wiki/Self-
balancing_binary_search_tree)
In computer science, a self-balancing (or height-balanced) binary search tree
is any node-based binary search tree that automatically keeps its height
small in the face of arbitrary item insertions and deletions.
postgres=# EXPLAIN ANALYZE SELECT * FROM foo WHERE name = 'text%';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Index Scan using idx_btree on foo (cost=0.43..8.45 rows=1 width=19) (actual time=0.015..0.015 rows=0 loops=1)
Index Cond: ((name)::text = 'text%'::text)
Planning Time: 0.105 ms
Execution Time: 0.031 ms
(4 rows)
© 2019 Percona
B-Tree Index 2/2
17
Page 0/N
Page 1/N
Page 2/N
Page N/N
Tuple - 1
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - 1
Tuple - n
Tuple - 3
Tuple - 2
Tuple - n
CREATE TABLE foo(id INTEGER, name TEXT, … );
INSERT INTO foo VALUES(1, 'Alex’, …);
INSERT INTO foo VALUES(2, ‘Bob, …
SELECT ctid, * FROM foo;
ctid | id | name …
-------+----+------
(0,1) | 1 | Alex …
(0,2) | 2 | Bob H
E
A
P
ctid | name
-------+------
(0,1) | Alex
(0,2) | Bob
Index have the key and the location of the tuple.
© 2019 Percona
HASH Index
• What is a Hash index?
• Hash indexes only handles equality operators
• Hash function is used to locate the tuples
18
CREATE INDEX idx_hash ON bar USING HASH (name);
postgres=# d bar
Table "public.bar"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
id | integer | | |
name | character varying | | |
dt | date | | |
Indexes:
"idx_btree" btree (name)
"idx_hash" btree (name)
EXPLAIN ANALYZE SELECT * FROM bar WHERE name = 'text%';
QUERY PLAN
Index Scan using idx_hash on bar (cost=0.43..8.45 rows=1 width=19) (actual time=0.023..0.023
rows=0 loops=1)
Index Cond: ((name)::text = 'text%'::text)
Planning Time: 0.080 ms
Execution Time: 0.041 ms
(4 rows)
© 2019 Percona
BRIN Index 1/3
• BRIN is a “Block Range Index”
• Used when columns have some correlation with their physical location in the table
• Space optimized because BRIN index contains only three items
• Page number
• Min value of column
• Max value of column
19
Like date, date of city have logical group
© 2019 Percona
BRIN Index 2/3
Sequential Scan
20
postgres=# EXPLAIN ANALYZE SELECT *
FROM bar
WHERE dt > '2022-09-28’
AND dt < '2022-10-28';
QUERY PLAN
------------------------------------------------------
Bitmap Heap Scan on bar (cost=92.03..61271.08 rows=1
width=27) (actual time=1.720..4.186 rows=29 loops=1)
Recheck Cond: ((dt > '2022-09-28 00:00:00’)
AND (dt < '2022-10-28 00:00:00'))
Rows Removed by Index Recheck: 18716
Heap Blocks: lossy=128
-> Bitmap Index Scan on idx_brin
(cost=0.00..92.03 rows=17406 width=0)
(actual time=1.456..1.456 rows=1280 loops=1)
Index Cond: ((dt > '2022-09-28 00:00:00’)
AND (dt < '2022-10-28 00:00:00'))
Planning Time: 0.130 ms
Execution Time: 4.233 ms
(8 rows)
postgres=# EXPLAIN ANALYZE SELECT *
FROM bar
WHERE dt > '2022-09-28’
AND dt < '2022-10-28';
QUERY PLAN
-----------------------------------------------------
Seq Scan on bar (cost=0.00..2235285.00 rows=1
width=27)
(actual time=0.139..7397.090 rows=29
loops=1)
Filter: ((dt > '2022-09-28 00:00:00)
AND (dt < '2022-10-28 00:00:00))
Rows Removed by Filter: 99999971
Planning Time: 0.114 ms
Execution Time: 7397.107 ms
(5 rows)
BRIN Index
© 2019 Percona
BRIN Index 3/3
21
• CREATE INDEX idx_btree ON bar USING BTREE (date);
• CREATE INDEX idx_hash ON bar USING HASH (date);
• CREATE INDEX idx_brin ON bar USING BRIN (date);
21504
48128
48
1
10
100
1000
10000
100000
Size of Index
(KB)
Index Sizes
B-Tree Hash BRIN
© 2019 Percona
GIN Index 1/2
• Generalized Inverted Index
• GIN is to handle where we need to index composite values
• Slow while creating the index because it needs to scan the document up front
22
postgres=# d bar
Table "public.bar"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | jsonb | | |
dt | date | | |
postgres=# SELECT DISTINCT name, dt FROM bar LIMIT 5;
name | dt
---------------------------------------------------------------------------+------------
{"name": "Alex", "phone": ["333-333-333", "222-222-222", "111-111-111"]} | 2019-05-13
{"name": "Bob", "phone": ["333-333-444", "222-222-444", "111-111-444"]} | 2019-05-14
{"name": "John", "phone": ["333-3333", "777-7777", "555-5555"]} | 2019-05-15
{"name": "David", "phone": ["333-333-555", "222-222-555", "111-111-555"]} | 2019-05-16
(4 rows)
© 2019 Percona
GIN Index 2/2
• Generalized Inverted Index
• GIN is to handle where we need to index composite values
• Slow while creating index because it needs to scan the document up front
23
postgres=# EXPLAIN ANALYZE SELECT * FROM bar
WHERE name @> '{"name": "Alex"}’;
QUERY PLAN
-----------------------------------------------------
Seq Scan on bar (cost=0.00..108309.34 rows=3499
width=96) (actual time=396.019..1050.143 rows=1000000
loops=1)
Filter: (name @> '{"name": "Alex"}'::jsonb)
Rows Removed by Filter: 3000000
Planning Time: 0.107 ms
Execution Time: 1079.861 ms
CREATE INDEX idx_gin ON bar USING GIN (name);
postgres=# EXPLAIN ANALYZE SELECT * FROM bar
WHERE name @> '{"name": "Alex"}';
QUERY PLAN
-----------------------------------------------------
Bitmap Heap Scan on bar (cost=679.00..13395.57
rows=4000 width=96) (actual time=91.110..445.112
rows=1000000 loops=1)
Recheck Cond: (name @> '{"name": "Alex"}'::jsonb)
Heap Blocks: exact=16394
-> Bitmap Index Scan on
idx_gin (cost=0.00..678.00 rows=4000 width=0)
(actual time=89.033..89.033 rows=1000000 loops=1)
Index Cond: (name @> '{"name":
"Alex"}'::jsonb)
Planning Time: 0.168 ms
Execution Time: 475.447 ms
© 2019 Percona
GiST Index
• Generalized Search Tree
• It is Tree-structured access method
• It is a indexing framework used for indexing of complex data types.
• Used to find the point within box
• Used for full text search
• Intarray
24
© 2019 Percona
Where and What?
• B-Tree: Use this index for most of the queries and different data types
• Hash: Used for equality operators
• BRIN: For really large sequentially lineup datasets
• GIN: Used for documents and arrays
• GiST: Used for full text search
25
© 2019 Percona
Index Only Scans
• Index is stored separately from the table’s main storage (PostgreSQL Heap)
• Query needs to scan both the index and the heap
• Index Only Scans only used when all the columns in the query part of the index
• In this case PostgreSQL fetches data from index only
26
In PostgreSQL term
© 2019 Percona
Index Only Scans
27
CREATE INDEX idx_btree_ios ON bar (id, name);
EXPLAIN SELECT id, name FROM bar WHERE id > 100000 AND id <100010;
QUERY PLAN
Index Only Scan using idx_btree_ios on bar (cost=0.56..99.20 rows=25 width=15)
Index Cond: ((id > 100000) AND (id < 100010))
(2 rows)
EXPLAIN SELECT id, name, dt FROM bar WHERE id > 100000 AND id <100010;
QUERY PLAN
Index Scan using idx_btree_ios on bar (cost=0.56..99.20 rows=25 width=19)
Index Cond: ((id > 100000) AND (id < 100010))
(2 rows)
© 2019 Percona
Duplicate Indexes
28
SELECT indrelid::regclass relname, indkey, amname
FROM pg_index i, pg_opclass o, pg_am a
WHERE o.oid = ALL (indclass)
AND a.oid = o.opcmethod
GROUP BY relname, indclass, amname, indkey
HAVING count(*) > 1;
relname | indkey | amname
---------+--------+--------
bar | 2 | btree
(1 row)
SELECT indrelid::regclass relname,
indexrelid::regclass indexname, indkey
FROM pg_index
GROUP BY relname,indexname,indkey;
relname | indexname | indkey
--------------------------+-----------------------------------------------+---------
pg_index | pg_index_indexrelid_index | 1
pg_toast.pg_toast_2615 | pg_toast.pg_toast_2615_index | 1 2
pg_constraint | pg_constraint_conparentid_index | 11
© 2019 Percona
Supported Data Types For A Particular Indexes
29
SELECT amname, opfname FROM pg_opfamily, pg_am WHERE opfmethod = pg_am.oid AND amname = ‘gin';
amname | opfname
--------+----------------
gin | array_ops
gin | tsvector_ops
gin | jsonb_ops
gin | jsonb_path_ops
SELECT amname, opfname FROM pg_opfamily, pg_am WHERE opfmethod = pg_am.oid AND amname = ‘gist';
amname | opfname
--------+--------------
gist | network_ops
gist | box_ops
gist | poly_ops
gist | circle_ops
gist | point_ops
gist | tsvector_ops
gist | tsquery_ops
gist | range_ops
gist | jsonb_ops
© 2019 Percona
Index Stats (pg_stat_user_indexes, pg_stat_statement)
30
postgres=# d pg_stat_user_indexes;
View "pg_catalog.pg_stat_user_indexes"
Column | Type | Collation | Nullable | Default
---------------+--------+-----------+----------+---------
relid | oid | | |
indexrelid | oid | | |
schemaname | name | | |
relname | name | | |
indexrelname | name | | |
idx_scan | bigint | | |
idx_tup_read | bigint | | |
idx_tup_fetch | bigint | | |
© 2019 Percona
Unused Indexes
31
SELECT relname, indexrelname, idx_scan
FROM pg_catalog.pg_stat_user_indexes;
relname | indexrelname | idx_scan
---------+---------------+----------
foo | idx_foo_date | 0
bar | idx_btree | 0
bar | idx_btree_id | 0
bar | idx_btree_name| 6
bar | idx_brin_brin | 4
(7 rows)
© 2019 Percona
?
“Poor leaders rarely ask questions of themselves or others. Good leaders, on the other
hand, ask many questions. Great leaders ask the great questions.”
Michael Marquardt author of
Leading with Questions

More Related Content

What's hot (20)

The MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer TraceThe MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer Trace
oysteing
 
The PostgreSQL Query Planner
The PostgreSQL Query PlannerThe PostgreSQL Query Planner
The PostgreSQL Query Planner
Command Prompt., Inc
 
The Parquet Format and Performance Optimization Opportunities
The Parquet Format and Performance Optimization OpportunitiesThe Parquet Format and Performance Optimization Opportunities
The Parquet Format and Performance Optimization Opportunities
Databricks
 
PostGreSQL Performance Tuning
PostGreSQL Performance TuningPostGreSQL Performance Tuning
PostGreSQL Performance Tuning
Maven Logix
 
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
Chester Chen
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6
MYXPLAIN
 
MySQL: Indexing for Better Performance
MySQL: Indexing for Better PerformanceMySQL: Indexing for Better Performance
MySQL: Indexing for Better Performance
jkeriaki
 
How to Use JSON in MySQL Wrong
How to Use JSON in MySQL WrongHow to Use JSON in MySQL Wrong
How to Use JSON in MySQL Wrong
Karwin Software Solutions LLC
 
Oracle Database Performance Tuning Concept
Oracle Database Performance Tuning ConceptOracle Database Performance Tuning Concept
Oracle Database Performance Tuning Concept
Chien Chung Shen
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
Arnab Mitra
 
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark ApplicationsTop 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Cloudera, Inc.
 
Course 102: Lecture 13: Regular Expressions
Course 102: Lecture 13: Regular Expressions Course 102: Lecture 13: Regular Expressions
Course 102: Lecture 13: Regular Expressions
Ahmed El-Arabawy
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo
 
Oracle Database SQL Tuning Concept
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
Chien Chung Shen
 
Oracle Performance Tuning Fundamentals
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning Fundamentals
Enkitec
 
Understanding oracle rac internals part 2 - slides
Understanding oracle rac internals   part 2 - slidesUnderstanding oracle rac internals   part 2 - slides
Understanding oracle rac internals part 2 - slides
Mohamed Farouk
 
PostgreSQL Advanced Queries
PostgreSQL Advanced QueriesPostgreSQL Advanced Queries
PostgreSQL Advanced Queries
Nur Hidayat
 
Advanced MySQL Query Tuning
Advanced MySQL Query TuningAdvanced MySQL Query Tuning
Advanced MySQL Query Tuning
Alexander Rubin
 
Postgresql
PostgresqlPostgresql
Postgresql
NexThoughts Technologies
 
Apache Iceberg: An Architectural Look Under the Covers
Apache Iceberg: An Architectural Look Under the CoversApache Iceberg: An Architectural Look Under the Covers
Apache Iceberg: An Architectural Look Under the Covers
ScyllaDB
 
The MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer TraceThe MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer Trace
oysteing
 
The Parquet Format and Performance Optimization Opportunities
The Parquet Format and Performance Optimization OpportunitiesThe Parquet Format and Performance Optimization Opportunities
The Parquet Format and Performance Optimization Opportunities
Databricks
 
PostGreSQL Performance Tuning
PostGreSQL Performance TuningPostGreSQL Performance Tuning
PostGreSQL Performance Tuning
Maven Logix
 
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
SF Big Analytics 20190612: Building highly efficient data lakes using Apache ...
Chester Chen
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6
MYXPLAIN
 
MySQL: Indexing for Better Performance
MySQL: Indexing for Better PerformanceMySQL: Indexing for Better Performance
MySQL: Indexing for Better Performance
jkeriaki
 
Oracle Database Performance Tuning Concept
Oracle Database Performance Tuning ConceptOracle Database Performance Tuning Concept
Oracle Database Performance Tuning Concept
Chien Chung Shen
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
Arnab Mitra
 
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark ApplicationsTop 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Cloudera, Inc.
 
Course 102: Lecture 13: Regular Expressions
Course 102: Lecture 13: Regular Expressions Course 102: Lecture 13: Regular Expressions
Course 102: Lecture 13: Regular Expressions
Ahmed El-Arabawy
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo
 
Oracle Database SQL Tuning Concept
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
Chien Chung Shen
 
Oracle Performance Tuning Fundamentals
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning Fundamentals
Enkitec
 
Understanding oracle rac internals part 2 - slides
Understanding oracle rac internals   part 2 - slidesUnderstanding oracle rac internals   part 2 - slides
Understanding oracle rac internals part 2 - slides
Mohamed Farouk
 
PostgreSQL Advanced Queries
PostgreSQL Advanced QueriesPostgreSQL Advanced Queries
PostgreSQL Advanced Queries
Nur Hidayat
 
Advanced MySQL Query Tuning
Advanced MySQL Query TuningAdvanced MySQL Query Tuning
Advanced MySQL Query Tuning
Alexander Rubin
 
Apache Iceberg: An Architectural Look Under the Covers
Apache Iceberg: An Architectural Look Under the CoversApache Iceberg: An Architectural Look Under the Covers
Apache Iceberg: An Architectural Look Under the Covers
ScyllaDB
 

Similar to Deep dive to PostgreSQL Indexes (20)

Индексируем базу: как делать хорошо и не делать плохо Winter saint p 2021 m...
Индексируем базу: как делать хорошо и не делать плохо   Winter saint p 2021 m...Индексируем базу: как делать хорошо и не делать плохо   Winter saint p 2021 m...
Индексируем базу: как делать хорошо и не делать плохо Winter saint p 2021 m...
Андрей Новиков
 
Flexible Indexing with Postgres
Flexible Indexing with PostgresFlexible Indexing with Postgres
Flexible Indexing with Postgres
EDB
 
Postgres indexes
Postgres indexesPostgres indexes
Postgres indexes
Bartosz Sypytkowski
 
Flexible Indexing with Postgres
Flexible Indexing with PostgresFlexible Indexing with Postgres
Flexible Indexing with Postgres
EDB
 
Postgres indexes: how to make them work for your application
Postgres indexes: how to make them work for your applicationPostgres indexes: how to make them work for your application
Postgres indexes: how to make them work for your application
Bartosz Sypytkowski
 
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
PROIDEA
 
B+Tree Indexes and InnoDB
B+Tree Indexes and InnoDBB+Tree Indexes and InnoDB
B+Tree Indexes and InnoDB
Ovais Tariq
 
Btree. Explore the heart of PostgreSQL.
Btree. Explore the heart of PostgreSQL. Btree. Explore the heart of PostgreSQL.
Btree. Explore the heart of PostgreSQL.
Anastasia Lubennikova
 
Postgres can do THAT?
Postgres can do THAT?Postgres can do THAT?
Postgres can do THAT?
alexbrasetvik
 
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep diveWebinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Severalnines
 
Введение в современную PostgreSQL. Часть 2
Введение в современную PostgreSQL. Часть 2Введение в современную PostgreSQL. Часть 2
Введение в современную PostgreSQL. Часть 2
Dzianis Pirshtuk
 
Postgres Performance for Humans
Postgres Performance for HumansPostgres Performance for Humans
Postgres Performance for Humans
Citus Data
 
Steam Learn: Introduction to RDBMS indexes
Steam Learn: Introduction to RDBMS indexesSteam Learn: Introduction to RDBMS indexes
Steam Learn: Introduction to RDBMS indexes
inovia
 
query-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdfquery-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdf
garos1
 
The NoSQL store everyone ignored
The NoSQL store everyone ignoredThe NoSQL store everyone ignored
The NoSQL store everyone ignored
Zohaib Hassan
 
SQL: Query optimization in practice
SQL: Query optimization in practiceSQL: Query optimization in practice
SQL: Query optimization in practice
Jano Suchal
 
Explain this!
Explain this!Explain this!
Explain this!
Fabio Telles Rodriguez
 
PostgreSQL 9.4: NoSQL on ACID
PostgreSQL 9.4: NoSQL on ACIDPostgreSQL 9.4: NoSQL on ACID
PostgreSQL 9.4: NoSQL on ACID
Oleg Bartunov
 
Postgres index types
Postgres index typesPostgres index types
Postgres index types
Louise Grandjonc
 
Advanced query optimization
Advanced query optimizationAdvanced query optimization
Advanced query optimization
MYXPLAIN
 
Индексируем базу: как делать хорошо и не делать плохо Winter saint p 2021 m...
Индексируем базу: как делать хорошо и не делать плохо   Winter saint p 2021 m...Индексируем базу: как делать хорошо и не делать плохо   Winter saint p 2021 m...
Индексируем базу: как делать хорошо и не делать плохо Winter saint p 2021 m...
Андрей Новиков
 
Flexible Indexing with Postgres
Flexible Indexing with PostgresFlexible Indexing with Postgres
Flexible Indexing with Postgres
EDB
 
Flexible Indexing with Postgres
Flexible Indexing with PostgresFlexible Indexing with Postgres
Flexible Indexing with Postgres
EDB
 
Postgres indexes: how to make them work for your application
Postgres indexes: how to make them work for your applicationPostgres indexes: how to make them work for your application
Postgres indexes: how to make them work for your application
Bartosz Sypytkowski
 
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
PROIDEA
 
B+Tree Indexes and InnoDB
B+Tree Indexes and InnoDBB+Tree Indexes and InnoDB
B+Tree Indexes and InnoDB
Ovais Tariq
 
Btree. Explore the heart of PostgreSQL.
Btree. Explore the heart of PostgreSQL. Btree. Explore the heart of PostgreSQL.
Btree. Explore the heart of PostgreSQL.
Anastasia Lubennikova
 
Postgres can do THAT?
Postgres can do THAT?Postgres can do THAT?
Postgres can do THAT?
alexbrasetvik
 
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep diveWebinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Webinar slides: MySQL Query Tuning Trilogy: Indexing and EXPLAIN - deep dive
Severalnines
 
Введение в современную PostgreSQL. Часть 2
Введение в современную PostgreSQL. Часть 2Введение в современную PostgreSQL. Часть 2
Введение в современную PostgreSQL. Часть 2
Dzianis Pirshtuk
 
Postgres Performance for Humans
Postgres Performance for HumansPostgres Performance for Humans
Postgres Performance for Humans
Citus Data
 
Steam Learn: Introduction to RDBMS indexes
Steam Learn: Introduction to RDBMS indexesSteam Learn: Introduction to RDBMS indexes
Steam Learn: Introduction to RDBMS indexes
inovia
 
query-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdfquery-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdf
garos1
 
The NoSQL store everyone ignored
The NoSQL store everyone ignoredThe NoSQL store everyone ignored
The NoSQL store everyone ignored
Zohaib Hassan
 
SQL: Query optimization in practice
SQL: Query optimization in practiceSQL: Query optimization in practice
SQL: Query optimization in practice
Jano Suchal
 
PostgreSQL 9.4: NoSQL on ACID
PostgreSQL 9.4: NoSQL on ACIDPostgreSQL 9.4: NoSQL on ACID
PostgreSQL 9.4: NoSQL on ACID
Oleg Bartunov
 
Advanced query optimization
Advanced query optimizationAdvanced query optimization
Advanced query optimization
MYXPLAIN
 
Ad

Recently uploaded (20)

Human body make Structure analysis the part of the human
Human body make Structure analysis the part of the humanHuman body make Structure analysis the part of the human
Human body make Structure analysis the part of the human
ankit392215
 
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptxMulti-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
VikashVats1
 
Internal Architecture of Database Management Systems
Internal Architecture of Database Management SystemsInternal Architecture of Database Management Systems
Internal Architecture of Database Management Systems
M Munim
 
Data Analytics and visualization-PowerBi
Data Analytics and visualization-PowerBiData Analytics and visualization-PowerBi
Data Analytics and visualization-PowerBi
Krishnapriya975316
 
Али махмуд to The teacm of ghsbh to fortune .pptx
Али махмуд to The teacm of ghsbh to fortune .pptxАли махмуд to The teacm of ghsbh to fortune .pptx
Али махмуд to The teacm of ghsbh to fortune .pptx
palr19411
 
Market Share Analysis.pptx nnnnnnnnnnnnnn
Market Share Analysis.pptx nnnnnnnnnnnnnnMarket Share Analysis.pptx nnnnnnnnnnnnnn
Market Share Analysis.pptx nnnnnnnnnnnnnn
rocky
 
Math arihant handbook.pdf all formula is here
Math arihant handbook.pdf all formula is hereMath arihant handbook.pdf all formula is here
Math arihant handbook.pdf all formula is here
rdarshankumar84
 
15 Benefits of Data Analytics in Business Growth.pdf
15 Benefits of Data Analytics in Business Growth.pdf15 Benefits of Data Analytics in Business Growth.pdf
15 Benefits of Data Analytics in Business Growth.pdf
AffinityCore
 
egc.pdf tài liệu tiếng Anh cho học sinh THPT
egc.pdf tài liệu tiếng Anh cho học sinh THPTegc.pdf tài liệu tiếng Anh cho học sinh THPT
egc.pdf tài liệu tiếng Anh cho học sinh THPT
huyenmy200809
 
Blue Dark Professional Geometric Business Project Presentation .pdf
Blue Dark Professional Geometric Business Project Presentation .pdfBlue Dark Professional Geometric Business Project Presentation .pdf
Blue Dark Professional Geometric Business Project Presentation .pdf
mohammadhaidarayoobi
 
delta airlines new york office (Airwayscityoffice)
delta airlines new york office (Airwayscityoffice)delta airlines new york office (Airwayscityoffice)
delta airlines new york office (Airwayscityoffice)
jamespromind
 
Chapter 5.1.pptxsertj you can get it done before the election and I will
Chapter 5.1.pptxsertj you can get it done before the election and I willChapter 5.1.pptxsertj you can get it done before the election and I will
Chapter 5.1.pptxsertj you can get it done before the election and I will
SotheaPheng
 
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docxHow Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
sofiawilliams5966
 
time_series_forecasting_constructor_uni.pptx
time_series_forecasting_constructor_uni.pptxtime_series_forecasting_constructor_uni.pptx
time_series_forecasting_constructor_uni.pptx
stefanopinto1113
 
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
JunZhao68
 
llm lecture 3 stanford blah blah blah blah
llm lecture 3 stanford blah blah blah blahllm lecture 3 stanford blah blah blah blah
llm lecture 3 stanford blah blah blah blah
saud140081
 
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptx
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptxArtificial-Intelligence-in-Autonomous-Vehicles (1).pptx
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptx
AbhijitPal87
 
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGePSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
Tomas Moser
 
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Karim Baïna
 
Arrays in c programing. practicals and .ppt
Arrays in c programing. practicals and .pptArrays in c programing. practicals and .ppt
Arrays in c programing. practicals and .ppt
Carlos701746
 
Human body make Structure analysis the part of the human
Human body make Structure analysis the part of the humanHuman body make Structure analysis the part of the human
Human body make Structure analysis the part of the human
ankit392215
 
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptxMulti-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
Multi-Agent-Solution-Architecture-for-Unified-Loan-Platform.pptx
VikashVats1
 
Internal Architecture of Database Management Systems
Internal Architecture of Database Management SystemsInternal Architecture of Database Management Systems
Internal Architecture of Database Management Systems
M Munim
 
Data Analytics and visualization-PowerBi
Data Analytics and visualization-PowerBiData Analytics and visualization-PowerBi
Data Analytics and visualization-PowerBi
Krishnapriya975316
 
Али махмуд to The teacm of ghsbh to fortune .pptx
Али махмуд to The teacm of ghsbh to fortune .pptxАли махмуд to The teacm of ghsbh to fortune .pptx
Али махмуд to The teacm of ghsbh to fortune .pptx
palr19411
 
Market Share Analysis.pptx nnnnnnnnnnnnnn
Market Share Analysis.pptx nnnnnnnnnnnnnnMarket Share Analysis.pptx nnnnnnnnnnnnnn
Market Share Analysis.pptx nnnnnnnnnnnnnn
rocky
 
Math arihant handbook.pdf all formula is here
Math arihant handbook.pdf all formula is hereMath arihant handbook.pdf all formula is here
Math arihant handbook.pdf all formula is here
rdarshankumar84
 
15 Benefits of Data Analytics in Business Growth.pdf
15 Benefits of Data Analytics in Business Growth.pdf15 Benefits of Data Analytics in Business Growth.pdf
15 Benefits of Data Analytics in Business Growth.pdf
AffinityCore
 
egc.pdf tài liệu tiếng Anh cho học sinh THPT
egc.pdf tài liệu tiếng Anh cho học sinh THPTegc.pdf tài liệu tiếng Anh cho học sinh THPT
egc.pdf tài liệu tiếng Anh cho học sinh THPT
huyenmy200809
 
Blue Dark Professional Geometric Business Project Presentation .pdf
Blue Dark Professional Geometric Business Project Presentation .pdfBlue Dark Professional Geometric Business Project Presentation .pdf
Blue Dark Professional Geometric Business Project Presentation .pdf
mohammadhaidarayoobi
 
delta airlines new york office (Airwayscityoffice)
delta airlines new york office (Airwayscityoffice)delta airlines new york office (Airwayscityoffice)
delta airlines new york office (Airwayscityoffice)
jamespromind
 
Chapter 5.1.pptxsertj you can get it done before the election and I will
Chapter 5.1.pptxsertj you can get it done before the election and I willChapter 5.1.pptxsertj you can get it done before the election and I will
Chapter 5.1.pptxsertj you can get it done before the election and I will
SotheaPheng
 
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docxHow Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
How Data Annotation Services Drive Innovation in Autonomous Vehicles.docx
sofiawilliams5966
 
time_series_forecasting_constructor_uni.pptx
time_series_forecasting_constructor_uni.pptxtime_series_forecasting_constructor_uni.pptx
time_series_forecasting_constructor_uni.pptx
stefanopinto1113
 
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
语法专题3-状语从句.pdf 英语语法基础部分,涉及到状语从句部分的内容来米爱上
JunZhao68
 
llm lecture 3 stanford blah blah blah blah
llm lecture 3 stanford blah blah blah blahllm lecture 3 stanford blah blah blah blah
llm lecture 3 stanford blah blah blah blah
saud140081
 
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptx
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptxArtificial-Intelligence-in-Autonomous-Vehicles (1).pptx
Artificial-Intelligence-in-Autonomous-Vehicles (1).pptx
AbhijitPal87
 
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGePSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
PSUG 7 - 2025-06-03 - David Bianco on Splunk SURGe
Tomas Moser
 
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Ethical Frameworks for Trustworthy AI – Opportunities for Researchers in Huma...
Karim Baïna
 
Arrays in c programing. practicals and .ppt
Arrays in c programing. practicals and .pptArrays in c programing. practicals and .ppt
Arrays in c programing. practicals and .ppt
Carlos701746
 
Ad

Deep dive to PostgreSQL Indexes

  • 1. © 2019 Percona Termini PostgreSQL di Deep Dee Intu
  • 2. © 2019 Percona Ibrar Ahmed Deep Dive Into PostgreSQL Indexes Learn PostgreSQL index Senior Database Architect - Percona LLC October – 16, 2019
  • 4. © 2019 Percona • Rows / Tuples stored in a table • Every table in PostgreSQL has physical disk file(s) postgres=# CREATE TABLE foo(id int, name text); postgres=# SELECT relfilenode FROM pg_class WHERE relname LIKE 'foo’; relfilenode ------------- 16384 • The physical files on disk can be seen in the PostgreSQL $PGDATA directory. $ ls -lrt $PGDATA/base/13680/16384 -rw------- 1 vagrant vagrant 0 Apr 29 11:48 $PGDATA/base/13680/16384 Tables (Heap) “Tuple” and “Rows” are synonym $PGDATA is Data Directory “pg_class” is system table to contain table information“Relfilenode” is table file name of that table “16384” is table filename • Tuple stored in a table does not have any order
  • 5. © 2019 Percona EXPLAIN SELECT name FROM bar; QUERY PLAN ---------------------------------------------------------------------------- Seq Scan on bar (cost=0.00..163693.05 rows=9999905 width=11 EXPLAIN SELECT name FROM bar WHERE id = 5432; QUERY PLAN ---------------------------------------------------------------------------- Gather (cost=1000.00..116776.94 rows=1 width=11) Workers Planned: 2 -> Parallel Seq Scan on bar (cost=0.00..115776.84 rows=1 width=11) Filter: (id = 5432) Tables (Heap) • Select whole table, must be a sequential scan. • Select table’s rows where id is 5432, it should not be a sequential scan. Make sense? Why?
  • 6. © 2019 Percona Selecting Data from HEAP Page 0/N Page 1/N Page 2/N Page N/N Tuple - 1 Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - n CREATE TABLE foo(id INTEGER, name TEXT); INSERT INTO foo VALUES(1, 'Alex'); INSERT INTO foo VALUES(2, 'Bob'); SELECT ctid, * FROM foo; ctid | id | name -------+----+------ (0,1) | 1 | Alex (0,2) | 2 | Bob (2 rows) H E A P • How to select the data from the HEAP? • Need to scan each and every page and look for the tuple in the page Cost?
  • 7. © 2019 Percona PostgreSQL Indexes https://www.postgresql.org/docs/current/indexes.html 7
  • 8. © 2019 Percona postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432; QUERY PLAN ---------------------------------------------------------------------------- Bitmap Heap Scan on bar (cost=939.93..64313.02 rows=50000 width=32) Recheck Cond: (id = 5432) -> Bitmap Index Scan on bar_idx (cost=0.00..927.43 rows=50000 width=0) Index Cond: (id = 5432) postgres=# CREATE INDEX bar_idx ON bar(id); postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432; QUERY PLAN ---------------------------------------------------------------------------- Seq Scan on bar (cost=0.00..159235.00 rows=38216 width=32) Filter: (id = 5432) Why Index? • Indexes are entry points for tables • Index used to locate the tuples in the table • The sole reason to have an index is performance • Index is stored separately from the table’s main storage (PostgreSQL Heap) • More storage required to store the index along with original table 64313/159235 * 100 = 40% Cost of the query
  • 9. © 2019 Percona postgres=# CREATE INDEX idx_btree ON bar(id); postgres=# SELECT relfilenode FROM pg_class WHERE relname LIKE ‘idx_btree’; relfilenode ------------- 16425 Index Physical file name of the index PostgreSQL’s Catalog for relations/index The physical file on disk can be seen in the PostgreSQL $PGDATA directory. $ ls -lrt $PGDATA/13680/16425 -rw-------1 vagrant vagrant 1073741824 Apr 29 13:05 $PGDATA/base/13680/16425 • PostgreSQL standard way to create a index (https://www.postgresql.org/docs/current/sql-createindex.html) • PostgreSQL index has its own file on disk.
  • 10. © 2019 Percona postgres=# CREATE INDEX bar_idx ON bar(id); Creating Index 1/2 ”bar” is a table and ”id” is column postgres=# EXPLAIN SELECT name FROM bar WHERE id = 5432; QUERY PLAN ---------------------------------------------------------------------- Bitmap Heap Scan on bar (cost=939.93..64313.02 rows=50000 width=32) Recheck Cond: (id = 5432) -> Bitmap Index Scan on bar_idx (cost=0.00..927.43 rows=50000 width=0) Index Cond: (id = 5432) • Index based on single column of the table
  • 11. © 2019 Percona CREATE INDEX CONCURRENTLY idx_btree ON bar USING BTREE(id); CREATE INDEX Time: 23025.372 ms (00:23.025) CREATE INDEX idx_btree ON bar USING BTREE(id); CREATE INDEX Time: 12303.172 ms (00:12.303) Creating Index 2/2 • PostgreSQL locks the table when creating index • CONCURRENTLY option creates the index without locking the table
  • 12. © 2019 Percona Expression Index 1/2 CREATE INDEX idx_exp ON bar (lower(name)); EXPLAIN SELECT * FROM bar WHERE lower(name) LIKE 'Text1'; QUERY PLAN ------------------------------------------------------------- Seq Scan on bar (cost=0.00..213694.00 rows=50000 width=40) Filter: (lower((name)::text) ~~ 'Text1'::text) EXPLAIN SELECT * FROM bar WHERE lower(name) LIKE 'Text1'; QUERY PLAN ----------------------------------------------------------------------------- Bitmap Heap Scan on bar (cost=1159.93..64658.02 rows=50000 width=40) Filter: (lower((name)::text) ~~ 'Text1'::text) -> Bitmap Index Scan on idx_exp (cost=0.00..1147.43 rows=50000 width=0) Index Cond: (lower((name)::text) = 'Text1'::text)
  • 13. © 2019 Percona Expression Index 2/2 postgres=# EXPLAIN SELECT * FROM bar WHERE (dt + (INTERVAL '2 days')) < now(); QUERY PLAN ------------------------------------------------------------------------------------- Bitmap Heap Scan on bar (cost=62449.77..184477.10 rows=3333333 width=40) Recheck Cond: ((dt + '2 days'::interval) < now()) -> Bitmap Index Scan on idx_math_exp (cost=0.00..61616.43 rows=3333333 width=0) Index Cond: ((dt + '2 days'::interval) < now()) postgres=# CREATE INDEX idx_math_exp ON bar((dt + (INTERVAL '2 days'))); postgres=# EXPLAIN SELECT * FROM bar WHERE (dt + (INTERVAL '2 days')) < now(); QUERY PLAN --------------------------------------------------------------- Seq Scan on bar (cost=0.00..238694.00 rows=3333333 width=40) Filter: ((dt + '2 days'::interval) < now())
  • 14. © 2019 Percona Partial Index 14 CREATE INDEX idx_part ON bar(id) where id < 1000; EXPLAIN SELECT * FROM bar WHERE id < 1000 AND name LIKE 'text1000’; QUERY PLAN ----------------------------------------------------------------------- Bitmap Heap Scan on bar (cost=199.44..113893.44 rows=16667 width=40) Recheck Cond: (id < 1000) Filter: ((name)::text ~~ 'text1000'::text) -> Bitmap Index Scan on idx_part (cost=0.00..195.28 rows=3333333 width=0) Index Cond: (id < 1000) SELECT pg_size_pretty(pg_total_relation_size('idx_part')); pg_size_pretty ---------------- 240 kB (1 row) CREATE INDEX idx_full ON bar(id); EXPLAIN SELECT * FROM bar WHERE id < 1000 AND name LIKE 'text1000’; QUERY PLAN ------------------------------------------------------------------------ -- Bitmap Heap Scan on bar (cost=61568.60..175262.59 rows=16667 width=40) Recheck Cond: (id < 1000) Filter: ((name)::text ~~ 'text1000'::text) -> Bitmap Index Scan on idx_full (cost=0.00..61564.43 rows=3333333 width=0) Index Cond: (id < 1000) SELECT pg_size_pretty(pg_total_relation_size('idx_full')); pg_size_pretty ---------------- 214 MB (1 row) Look at the size of the index Why create full index if we don’t need that. Index Partial Index Index where id < 1000 only Q: What will happen when we query where id >1000? A: Answer is simple, this index won’t selected.
  • 15. © 2019 Percona Index Types https://www.postgresql.org/docs/current/indexes-types.html
  • 16. © 2019 Percona B-Tree Index 1/2 16 CREATE INDEX idx_btree ON foo USING BTREE (name); • What is a B-Tree index? • Supported Operators • Less than < • Less than equal to <= • Equal = • Greater than equal to >= • Greater than > Wikipedia: (https://en.wikipedia.org/wiki/Self- balancing_binary_search_tree) In computer science, a self-balancing (or height-balanced) binary search tree is any node-based binary search tree that automatically keeps its height small in the face of arbitrary item insertions and deletions. postgres=# EXPLAIN ANALYZE SELECT * FROM foo WHERE name = 'text%'; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Index Scan using idx_btree on foo (cost=0.43..8.45 rows=1 width=19) (actual time=0.015..0.015 rows=0 loops=1) Index Cond: ((name)::text = 'text%'::text) Planning Time: 0.105 ms Execution Time: 0.031 ms (4 rows)
  • 17. © 2019 Percona B-Tree Index 2/2 17 Page 0/N Page 1/N Page 2/N Page N/N Tuple - 1 Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - 1 Tuple - n Tuple - 3 Tuple - 2 Tuple - n CREATE TABLE foo(id INTEGER, name TEXT, … ); INSERT INTO foo VALUES(1, 'Alex’, …); INSERT INTO foo VALUES(2, ‘Bob, … SELECT ctid, * FROM foo; ctid | id | name … -------+----+------ (0,1) | 1 | Alex … (0,2) | 2 | Bob H E A P ctid | name -------+------ (0,1) | Alex (0,2) | Bob Index have the key and the location of the tuple.
  • 18. © 2019 Percona HASH Index • What is a Hash index? • Hash indexes only handles equality operators • Hash function is used to locate the tuples 18 CREATE INDEX idx_hash ON bar USING HASH (name); postgres=# d bar Table "public.bar" Column | Type | Collation | Nullable | Default --------+-------------------+-----------+----------+--------- id | integer | | | name | character varying | | | dt | date | | | Indexes: "idx_btree" btree (name) "idx_hash" btree (name) EXPLAIN ANALYZE SELECT * FROM bar WHERE name = 'text%'; QUERY PLAN Index Scan using idx_hash on bar (cost=0.43..8.45 rows=1 width=19) (actual time=0.023..0.023 rows=0 loops=1) Index Cond: ((name)::text = 'text%'::text) Planning Time: 0.080 ms Execution Time: 0.041 ms (4 rows)
  • 19. © 2019 Percona BRIN Index 1/3 • BRIN is a “Block Range Index” • Used when columns have some correlation with their physical location in the table • Space optimized because BRIN index contains only three items • Page number • Min value of column • Max value of column 19 Like date, date of city have logical group
  • 20. © 2019 Percona BRIN Index 2/3 Sequential Scan 20 postgres=# EXPLAIN ANALYZE SELECT * FROM bar WHERE dt > '2022-09-28’ AND dt < '2022-10-28'; QUERY PLAN ------------------------------------------------------ Bitmap Heap Scan on bar (cost=92.03..61271.08 rows=1 width=27) (actual time=1.720..4.186 rows=29 loops=1) Recheck Cond: ((dt > '2022-09-28 00:00:00’) AND (dt < '2022-10-28 00:00:00')) Rows Removed by Index Recheck: 18716 Heap Blocks: lossy=128 -> Bitmap Index Scan on idx_brin (cost=0.00..92.03 rows=17406 width=0) (actual time=1.456..1.456 rows=1280 loops=1) Index Cond: ((dt > '2022-09-28 00:00:00’) AND (dt < '2022-10-28 00:00:00')) Planning Time: 0.130 ms Execution Time: 4.233 ms (8 rows) postgres=# EXPLAIN ANALYZE SELECT * FROM bar WHERE dt > '2022-09-28’ AND dt < '2022-10-28'; QUERY PLAN ----------------------------------------------------- Seq Scan on bar (cost=0.00..2235285.00 rows=1 width=27) (actual time=0.139..7397.090 rows=29 loops=1) Filter: ((dt > '2022-09-28 00:00:00) AND (dt < '2022-10-28 00:00:00)) Rows Removed by Filter: 99999971 Planning Time: 0.114 ms Execution Time: 7397.107 ms (5 rows) BRIN Index
  • 21. © 2019 Percona BRIN Index 3/3 21 • CREATE INDEX idx_btree ON bar USING BTREE (date); • CREATE INDEX idx_hash ON bar USING HASH (date); • CREATE INDEX idx_brin ON bar USING BRIN (date); 21504 48128 48 1 10 100 1000 10000 100000 Size of Index (KB) Index Sizes B-Tree Hash BRIN
  • 22. © 2019 Percona GIN Index 1/2 • Generalized Inverted Index • GIN is to handle where we need to index composite values • Slow while creating the index because it needs to scan the document up front 22 postgres=# d bar Table "public.bar" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- id | integer | | | name | jsonb | | | dt | date | | | postgres=# SELECT DISTINCT name, dt FROM bar LIMIT 5; name | dt ---------------------------------------------------------------------------+------------ {"name": "Alex", "phone": ["333-333-333", "222-222-222", "111-111-111"]} | 2019-05-13 {"name": "Bob", "phone": ["333-333-444", "222-222-444", "111-111-444"]} | 2019-05-14 {"name": "John", "phone": ["333-3333", "777-7777", "555-5555"]} | 2019-05-15 {"name": "David", "phone": ["333-333-555", "222-222-555", "111-111-555"]} | 2019-05-16 (4 rows)
  • 23. © 2019 Percona GIN Index 2/2 • Generalized Inverted Index • GIN is to handle where we need to index composite values • Slow while creating index because it needs to scan the document up front 23 postgres=# EXPLAIN ANALYZE SELECT * FROM bar WHERE name @> '{"name": "Alex"}’; QUERY PLAN ----------------------------------------------------- Seq Scan on bar (cost=0.00..108309.34 rows=3499 width=96) (actual time=396.019..1050.143 rows=1000000 loops=1) Filter: (name @> '{"name": "Alex"}'::jsonb) Rows Removed by Filter: 3000000 Planning Time: 0.107 ms Execution Time: 1079.861 ms CREATE INDEX idx_gin ON bar USING GIN (name); postgres=# EXPLAIN ANALYZE SELECT * FROM bar WHERE name @> '{"name": "Alex"}'; QUERY PLAN ----------------------------------------------------- Bitmap Heap Scan on bar (cost=679.00..13395.57 rows=4000 width=96) (actual time=91.110..445.112 rows=1000000 loops=1) Recheck Cond: (name @> '{"name": "Alex"}'::jsonb) Heap Blocks: exact=16394 -> Bitmap Index Scan on idx_gin (cost=0.00..678.00 rows=4000 width=0) (actual time=89.033..89.033 rows=1000000 loops=1) Index Cond: (name @> '{"name": "Alex"}'::jsonb) Planning Time: 0.168 ms Execution Time: 475.447 ms
  • 24. © 2019 Percona GiST Index • Generalized Search Tree • It is Tree-structured access method • It is a indexing framework used for indexing of complex data types. • Used to find the point within box • Used for full text search • Intarray 24
  • 25. © 2019 Percona Where and What? • B-Tree: Use this index for most of the queries and different data types • Hash: Used for equality operators • BRIN: For really large sequentially lineup datasets • GIN: Used for documents and arrays • GiST: Used for full text search 25
  • 26. © 2019 Percona Index Only Scans • Index is stored separately from the table’s main storage (PostgreSQL Heap) • Query needs to scan both the index and the heap • Index Only Scans only used when all the columns in the query part of the index • In this case PostgreSQL fetches data from index only 26 In PostgreSQL term
  • 27. © 2019 Percona Index Only Scans 27 CREATE INDEX idx_btree_ios ON bar (id, name); EXPLAIN SELECT id, name FROM bar WHERE id > 100000 AND id <100010; QUERY PLAN Index Only Scan using idx_btree_ios on bar (cost=0.56..99.20 rows=25 width=15) Index Cond: ((id > 100000) AND (id < 100010)) (2 rows) EXPLAIN SELECT id, name, dt FROM bar WHERE id > 100000 AND id <100010; QUERY PLAN Index Scan using idx_btree_ios on bar (cost=0.56..99.20 rows=25 width=19) Index Cond: ((id > 100000) AND (id < 100010)) (2 rows)
  • 28. © 2019 Percona Duplicate Indexes 28 SELECT indrelid::regclass relname, indkey, amname FROM pg_index i, pg_opclass o, pg_am a WHERE o.oid = ALL (indclass) AND a.oid = o.opcmethod GROUP BY relname, indclass, amname, indkey HAVING count(*) > 1; relname | indkey | amname ---------+--------+-------- bar | 2 | btree (1 row) SELECT indrelid::regclass relname, indexrelid::regclass indexname, indkey FROM pg_index GROUP BY relname,indexname,indkey; relname | indexname | indkey --------------------------+-----------------------------------------------+--------- pg_index | pg_index_indexrelid_index | 1 pg_toast.pg_toast_2615 | pg_toast.pg_toast_2615_index | 1 2 pg_constraint | pg_constraint_conparentid_index | 11
  • 29. © 2019 Percona Supported Data Types For A Particular Indexes 29 SELECT amname, opfname FROM pg_opfamily, pg_am WHERE opfmethod = pg_am.oid AND amname = ‘gin'; amname | opfname --------+---------------- gin | array_ops gin | tsvector_ops gin | jsonb_ops gin | jsonb_path_ops SELECT amname, opfname FROM pg_opfamily, pg_am WHERE opfmethod = pg_am.oid AND amname = ‘gist'; amname | opfname --------+-------------- gist | network_ops gist | box_ops gist | poly_ops gist | circle_ops gist | point_ops gist | tsvector_ops gist | tsquery_ops gist | range_ops gist | jsonb_ops
  • 30. © 2019 Percona Index Stats (pg_stat_user_indexes, pg_stat_statement) 30 postgres=# d pg_stat_user_indexes; View "pg_catalog.pg_stat_user_indexes" Column | Type | Collation | Nullable | Default ---------------+--------+-----------+----------+--------- relid | oid | | | indexrelid | oid | | | schemaname | name | | | relname | name | | | indexrelname | name | | | idx_scan | bigint | | | idx_tup_read | bigint | | | idx_tup_fetch | bigint | | |
  • 31. © 2019 Percona Unused Indexes 31 SELECT relname, indexrelname, idx_scan FROM pg_catalog.pg_stat_user_indexes; relname | indexrelname | idx_scan ---------+---------------+---------- foo | idx_foo_date | 0 bar | idx_btree | 0 bar | idx_btree_id | 0 bar | idx_btree_name| 6 bar | idx_brin_brin | 4 (7 rows)
  • 32. © 2019 Percona ? “Poor leaders rarely ask questions of themselves or others. Good leaders, on the other hand, ask many questions. Great leaders ask the great questions.” Michael Marquardt author of Leading with Questions