efficient use of indexes in mysql

23
Indexes in MySQL Aleksandr Kuzminsky https://twindb.com How to use indexes efficiently

Upload: aleksandr-kuzminsky

Post on 06-Aug-2015

770 views

Category:

Internet


2 download

TRANSCRIPT

Page 1: Efficient Use of indexes in MySQL

Indexes in MySQLAleksandr Kuzminsky

https://twindb.com

How to use indexes efficiently

Page 2: Efficient Use of indexes in MySQL

Agenda

1. How data is organized2. Data access

Page 3: Efficient Use of indexes in MySQL

Who we are

Aleks:● TwinDB co-founder● Dropbox DBA● ex-Percona consultant

Ovais:● TwinDB co-founder● Lithium lead DBA● ex-Percona consultant

Page 4: Efficient Use of indexes in MySQL

How data is organized

Page 5: Efficient Use of indexes in MySQL

Table in MySQL (InnoDB)

CREATE TABLE `actor`( `actor_id` SMALLINT(5) UNSIGNED NOT NULL, `first_name` VARCHAR(45) NOT NULL, `last_name` VARCHAR(45) NOT NULL, `last_update` TIMESTAMP NOT NULL, PRIMARY KEY (`actor_id`), KEY `idx_actor_last_name` (`last_name`) ) ENGINE=InnoDB;

Page 6: Efficient Use of indexes in MySQL

B+ Tree

● O(log(n))● Shallow● Data in leaf pages

Page 7: Efficient Use of indexes in MySQL

sakila.actor

PRIMARY idx_actor_last_name

actor_id first_name last_name last_update

1 PENELOPE GUINESS 2006-02-15 04:34:33

2 NICK WAHLBERG 2006-02-15 04:34:33

3 ED CHASE 2006-02-15 04:34:33

4 JENNIFER DAVIS 2006-02-15 04:34:33

5 JOHNNY WOOD 2006-02-15 04:34:33

... ... ... ...

last_name actor_id

AKROYD 58

AKROYD 92

AKROYD 182

ALLEN 118

ALLEN 145

... ...

Page 8: Efficient Use of indexes in MySQL

Data Access

Fast if accessing table

andproducing result

is simultaneous

Page 9: Efficient Use of indexes in MySQL

Point SELECT

SELECT * FROM actor WHERE actor_id = 3;

actor_id first_name last_name last_update

1 PENELOPE GUINESS 2006-02-15 04:34:33

2 NICK WAHLBERG 2006-02-15 04:34:33

3 ED CHASE 2006-02-15 04:34:33

4 JENNIFER DAVIS 2006-02-15 04:34:33

5 JOHNNY WOOD 2006-02-15 04:34:33

... ... ... ...

Page 10: Efficient Use of indexes in MySQL

SELECT by range of keys

SELECT * FROM actor WHERE actor_id > 3;

actor_id first_name last_name last_update

1 PENELOPE GUINESS 2006-02-15 04:34:33

2 NICK WAHLBERG 2006-02-15 04:34:33

3 ED CHASE 2006-02-15 04:34:33

4 JENNIFER DAVIS 2006-02-15 04:34:33

5 JOHNNY WOOD 2006-02-15 04:34:33

... ... ... ...

Page 11: Efficient Use of indexes in MySQL

Lookup by secondary key

actor_id first_name last_name last_update

117 RENEE TRACY 2006-02-15 04:34:33

118 CUBA ALLEN 2006-02-15 04:34:33

119 WARREN JACKMAN 2006-02-15 04:34:33

... ... ... ...

145 KIM ALLEN 2006-02-15 04:34:33

... ... ... ...

last_name actor_id

AKROYD 58

AKROYD 92

AKROYD 182

ALLEN 118

ALLEN 145

... ...

SELECT * FROM actor WHERE last_name = ‘ALLEN’;

Step 1 Step 2

Page 12: Efficient Use of indexes in MySQL

Using index for data access

last_name actor_id

AKROYD 182

ALLEN 118

ALLEN 145

ALLEN 194

ASTAIRE 76

... ...

SELECT COUNT(*) FROM actor WHERE last_name = ‘ALLEN’;

Page 13: Efficient Use of indexes in MySQL

Using index for data access

EXPLAIN SELECT COUNT(*) FROM actor WHERE last_name = ‘ALLEN’;

*************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: refpossible_keys: idx_actor_last_name key: idx_actor_last_name key_len: 137 ref: const rows: 3 Extra: Using where; Using index

Page 14: Efficient Use of indexes in MySQL

Covering indexesALTER TABLE actor ADD INDEX idx_last_first(last_name, first_name);SELECT first_name FROM actor WHERE last_name = 'ALLEN'

last_name first_name actor_id

AKROYD KIRSTEN 182

ALLEN CUBA 118

ALLEN KIM 145

ALLEN MERYL 194

ASTAIRE ANGELINA 76

... ...

*************************** 1. row ***************************

id: 1 select_type: SIMPLE table: actor type: refpossible_keys: idx_actor_last_name,idx_last_first key: idx_last_first key_len: 137 ref: const rows: 3 Extra: Using where; Using index

Page 15: Efficient Use of indexes in MySQL

DISTINCT

*************************** 1. row ***************************

id: 1 select_type: SIMPLE table: actor type: indexpossible_keys: idx_actor_last_name,idx_last_first key: idx_actor_last_name key_len: 137 ref: NULL rows: 200 Extra: Using index

last_name actor_id

AKROYD 182

ALLEN 118

ALLEN 145

ALLEN 194

ASTAIRE 76

... ...

SELECT DISTINCT last_name FROM actor

Page 16: Efficient Use of indexes in MySQL

GROUP BY

*************************** 1. row ***************************

id: 1 select_type: SIMPLE table: actor type: indexpossible_keys: idx_actor_last_name,idx_last_first key: idx_actor_last_name key_len: 137 ref: NULL rows: 200 Extra: Using index

last_name actor_id

AKROYD 182

ALLEN 118

ALLEN 145

ALLEN 194

ASTAIRE 76

... ...

SELECT last_name, COUNT(*) FROM actor GROUP BY last_name

Page 17: Efficient Use of indexes in MySQL

Loose index scanALTER TABLE actor ADD COLUMN rank INT;UPDATE actor SET rank = ROUND(100 * RAND()); ALTER TABLE actor ADD INDEX idx_last_rank (last_name, rank);

last_name rank actor_id

AKROYD 40 58

AKROYD 42 92

AKROYD 95 182

ALLEN 19 194

ALLEN 35 118

... ...

Page 18: Efficient Use of indexes in MySQL

Loose index scan

SELECT last_name, MIN(rank) FROM actor GROUP BY last_name

last_name rank actor_id

AKROYD 40 58

AKROYD 42 92

AKROYD 95 182

ALLEN 19 194

ALLEN 35 118

... ...

*************************** 1. row ***************************

id: 1 select_type: SIMPLE table: actor type: rangepossible_keys: …, idx_last_rank key: idx_last_rank key_len: 137 ref: NULL rows: 247 Extra: Using index for group-by

Page 19: Efficient Use of indexes in MySQL

Sorting

SELECT * FROM actor WHERE last_name = 'AKROYD' ORDER BY rank

last_name rank actor_id

AKROYD 40 58

AKROYD 42 92

AKROYD 95 182

ALLEN 19 194

ALLEN 35 118

... ...

*************************** 1. row ***************************

id: 1 select_type: SIMPLE table: actor type: refpossible_keys: …, idx_last_rank key: idx_last_rank key_len: 137 ref: const rows: 3 Extra: Using where

Page 20: Efficient Use of indexes in MySQL

Joining tablesSELECT title, first_name, last_name

FROM film

JOIN film_actor

ON film_actor.film_id = film.film_id

JOIN actor

ON actor.actor_id = film_actor.actor_id

ORDER BY title;

Page 21: Efficient Use of indexes in MySQL

Joining tablesSELECT title, first_name, last_name

FROM film FORCE INDEX (`idx_title`)

JOIN film_actor

ON film_actor.film_id = film.film_id

JOIN actor

ON actor.actor_id = film_actor.actor_id

ORDER BY title;

Page 22: Efficient Use of indexes in MySQL

How to compare efficiency

Page 23: Efficient Use of indexes in MySQL

Q&A

Thank you!