Need For Speed: MySQL Indexing
Need For Speed: MySQL Indexing
com
[email protected]
1 / 30
www.fromdual.com
www.fromdual.com
2 / 30
Unsere Kunden
www.fromdual.com
3 / 30
www.fromdual.com
MySQL Dokumentation:
The best way to improve the performance of SELECT operations is
to create indexes on one or more of the columns that are tested in
the query.
Grossartig! Aber:
Unnecessary indexes waste space and waste time to determine
which indexes to use. You must find the right balance to achieve
fast queries using the optimal set of indexes.
... hmmm, somit mssen wir wohl ein bisschen denken... :-(
4 / 30
Adams, Douglas:
The Hitchhiker's
Guide to the
Galaxy?
www.fromdual.com
Sennhauser, Oli,
Uster?
5 / 30
www.fromdual.com
MyISAM
InnoDB
6 / 30
www.fromdual.com
7 / 30
WHERE Klausel 1
www.fromdual.com
SELECT*
FROMcustomers
SHOWCREATETABLEcustomers\G
WHEREname='FromDual';
CREATETABLE`customers`(
`customer_id`smallint(5)unsigned
,`name`varchar(64)DEFAULTNULL
,PRIMARYKEY(`customer_id`)
)
EXPLAIN
SELECT*
FROMcustomers
WHEREname='FromDual';
+++++++
|table|type|possible_keys|key|rows|Extra|
+++++++
|customers|ALL|NULL|NULL|31978|Usingwhere|
+++++++
8 / 30
www.fromdual.com
ALTERTABLE
ADDPRIMARYKEY(id);
ADDUNIQUEKEY(uuid);
ADDFOREIGNKEY(customer_id)
REFERENCEScustomers(customer_id);
ADDINDEX(last_name,first_name);
ADDINDEXpre_ind(hash(8));
ADDFULLTEXTINDEX(last_name,
first_name);
9 / 30
WHERE Klausel 2
www.fromdual.com
ALTERTABLEcustomers
ADDINDEX(name);
CREATETABLE`customers`(
`customer_id`smallint(5)unsigned
Verbesserung:
20 ms 5 ms
,`name`varchar(64)DEFAULTNULL
,PRIMARYKEY(`customer_id`)
,KEY`name`(`name`)
)
+-----------+------+---------------+------+---------+-------+------+
| table
| type | possible_keys | key | key_len | ref
| rows |
+-----------+------+---------------+------+---------+-------+------+
| customers | ref | name
| name | 67
| const |
1 |
+-----------+------+---------------+------+---------+-------+------+
10 / 30
JOIN Klausel
www.fromdual.com
EXPLAINSELECT*
FROMcustomersASc
JOINordersASoONc.customer_id=o.customer_id
WHEREc.name='FromDual';
++++++++
|table|type|possible_keys|key|key_len|ref|rows|
++++++++
|c|ref|PRIMARY,name|name|67|const|1|
|o|ALL|NULL|NULL|NULL|NULL|1045105|
++++++++
Verbesserung: 450 ms 6 ms
ALTERTABLEorders
ADDINDEX(customer_id);
+-------+------+---------------+-------------+---------+---------------+------+
| table | type | possible_keys | key
| key_len | ref
| rows |
+-------+------+---------------+-------------+---------+---------------+------+
| c
| ref | PRIMARY,name | name
| 67
| const
|
1 |
| o
| ref | customer_id
| customer_id | 3
| c.customer_id |
8 |
+-------+------+---------------+-------------+---------+---------------+------+
11 / 30
www.fromdual.com
ORDERBY,GROUPBY
EXPLAINSELECT*
FROMcontactsASc
WHERElast_name='Sennhauser'
ORDERBYlast_name,first_name;
++++++
|table|type|key|rows|Extra|
++++++
|c|ref|last_name|1561|Usingindexcondition;Usingwhere;Usingfilesort|
++++++
Verbesserung : 20 ms 7 ms
ALTERTABLEcontacts
ADDINDEX(last_name,first_name);
++++++
|table|type|key|rows|Extra|
++++++
|c|ref|last_name_2|1561|Usingwhere;Usingindex|
++++++
12 / 30
Covering Indices
www.fromdual.com
EXPLAIN
SELECTcustomer_id,amount
FROMordersASo
WHEREcustomer_id=59349;
++++++
|table|type|key|rows|Extra|
++++++
Und jetzt?
|o|ref|customer_id|15|NULL|
++++++
ALTERTABLEorders
ADDINDEX(customer_id,amount);
++++++
|table|type|key|rows|Extra|
++++++
|o|ref|customer_id_2|15|Usingindex|
++++++
13 / 30
www.fromdual.com
ohne
mit
14 / 30
www.fromdual.com
ER Diagramm? :-(
Hngt hauptschlich von der Business
Logik ab...
Wie FINDET man sie? --> Slow Query Log
MySQL Variablen:
Seit v5.1
on-line!
+-------------------------------+----------+
| Variable_name
| Value
|
+-------------------------------+----------+
| log_queries_not_using_indexes | ON
|
| long_query_time
| 0.250000 |
| min_examined_row_limit
| 100
|
| slow_query_log
| ON
|
| slow_query_log_file
| slow.log |
+-------------------------------+----------+
15 / 30
www.fromdual.com
16 / 30
www.fromdual.com
Prefixed Index:
ADDINDEXpre_ind(hash(8));
17 / 30
Indices vermeiden
www.fromdual.com
18 / 30
www.fromdual.com
SHOWCREATETABLE...\G
mysqldumpnodata>structure_dump.sql
http://fromdual.com/mysql-performance-schema-hints
SELECT
FROM
WHERE
AND
ORDER
www.fromdual.com
INDEX(city,last_name,first_name)
INDEX(city,last_name)
INDEX(city)
INDEX(last_name,city) ???
INDEX(first_name,last_name) !!!
20 / 30
Schlechte Selektivitt
status
gender
active
www.fromdual.com
www.fromdual.com
InnoDB PK und SK
www.fromdual.com
InnoDB kennt
23 / 30
Geclusterter Index
www.fromdual.com
Beispiel: InnoDB
www.fromdual.com
A_Itsv_idxposypos...
117:30#42x,y,...
217:30#43x,y,...
317:30#44x,y,...
#42
alle 2'
...
200117:32#42x,y,...
200217:32#43x,y,...
200317:32#44x,y,...
Q1: in Zeilen? ~ 2000 Zeilen
A1: 1 Zeile ~ 100 byte
Q2: in bytes? ~ 200 kbyte
Q3: Default InnoDB block size? default: 16 kbyte
Q4: Avg. # Zeilen von LKW #42 in 1 InnoDB block? ~ 1
A2: 3 d und 720 pt/d ~2000 pt ~ 2000 rec ~ 2000 blk
Q5: Wie lange dauert das und warum (32 Mbyte)?
~ 2000 IOPS ~ 10s random read!!!
S: Alles im RAM oder starkes I/O-System oder ?
2000 LKWs
www.fromdual.com
tsv_idxposypos...
17:30#42x,y,...
17:32#42x,y,...
17:34#42x,y,...
...
#42
alle 2'
17:30#43x,y,...
17:32#43x,y,...
17:34#43x,y,...
...
17:30#44x,y,...
2000 LKWs
Index Hints
www.fromdual.com
USEINDEX(ind1,ind2)
Schau nur diese Indices an...
FORCEINDEX(ind3)
27 / 30
MySQL Variablen
www.fromdual.com
MyISAM: key_buffer_size
InnoDB: innodb_buffer_pool_size
innodb_change_buffer_max_size
innodb_change_buffering
innodb_large_prefix
28 / 30
www.fromdual.com
Q&A
www.fromdual.com
Fragen ?
Diskussion?
Anschliessend ist noch Zeit fr ein persnliches Gesprch...
MySQL Beratung
Remote-DBA
MySQL Schulung
www.fromdual.com/presentations
30 / 30