are you getting the best out of your mysql indexes? · up to 767 bytes on innodb, 1000 on myisam...
TRANSCRIPT
![Page 1: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/1.jpg)
Are You Getting the Best Out of Your MySQL Indexes?
Sheeri CabralSenior DB Admin/Architect, Mozilla
@sheeri www.sheeri.com
Slideshttp://bit.ly/mysqlindex2
![Page 2: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/2.jpg)
What is an index?
![Page 3: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/3.jpg)
KEY vs. INDEX
KEY = KEY CONSTRAINT
PRIMARY, UNIQUE, FOREIGN
Everything else is an “implementation detail”
The plural of INDEX is....?
![Page 4: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/4.jpg)
http://www.sheldoncomics.com/strips/sd120626.png
![Page 5: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/5.jpg)
More Lingo
Simple
(last_name)
Composite
(last_name,first_name)
![Page 6: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/6.jpg)
Data Structures
B-TREE for InnoDB, MyISAM
Can be HASH for MEMORY
![Page 7: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/7.jpg)
B-tree
(Image from Wikipedia)
![Page 8: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/8.jpg)
B-trees Are Excellent For...
A range search - foo BETWEEN 5 AND 10
One equality match - foo=11
A few equality matches - foo IN (5,10,11)
- How is it done?
(Image from Wikipedia)
![Page 9: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/9.jpg)
Composite Indexes
Index on (last_name,first_name)
Used find words beginning with “g” (last_name)
Not used to find words ending with “g” (first_name)
OK to have (last_name,first_name) and (first_name)
Like a dictionary index
(Image from Wikipedia)
![Page 10: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/10.jpg)
MySQL Uses Indexes For...
Matching a WHERE clause
Eliminating rows
Resolving MIN() or MAX() values
Eliminating sorting
Helping with grouping
Everything – Covering index
(Image from Wikipedia)
![Page 11: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/11.jpg)
MySQL Ignores Indexes For...
Functions
DATE(ts_col)='2012_08_11'
JOINs if the fields are not similar
date_col='2012_08_11 00:00:00'
(Image from Wikipedia)
![Page 12: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/12.jpg)
MySQL Ignores Indexes For...
Queries with multiple WHERE clauses
not all using the same index
joined by OR
For example, imagine a test table, with an index on (last_name,first_name)
![Page 13: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/13.jpg)
test,(last_name,first_name)
Queries that use the index:
SELECT * FROM test WHERE last_name='Cabral';
SELECT * FROM test
WHERE last_name='Cabral' AND first_name='Sheeri';
SELECT * FROM test
WHERE last_name='Cabral'
AND (first_name='Tony' OR first_name='Antonio');
![Page 14: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/14.jpg)
test,(last_name,first_name)
Queries that DO NOT use the index:
SELECT * FROM test WHERE first_name='Sheeri';
SELECT * FROM test
WHERE last_name='Cabral' OR first_name='Sheeri';
![Page 15: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/15.jpg)
Composite Indexes
Index on (last_name,first_name,middle_name)
Functions as:
(last_name,first_name,middle_name)
(last_name,first_name)
(last_name)
![Page 16: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/16.jpg)
MySQL Ignores Indexes For...
“Too much” data, just do a full table scan (7,9,12)
6 lookups vs. walking the 10-node tree
(Image from Wikipedia)
(Image from Wikipedia)
![Page 17: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/17.jpg)
“Too Much” Data
“Too much” is about 15-25%
How is that calculated?
![Page 18: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/18.jpg)
Metadata!
Exact in MyISAM (writes are table-locking)
Approximate in InnoDB
“value group”
Average value group size
Used for approx rows for rows read, joins
![Page 19: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/19.jpg)
Average Value Group Size
Body parts: 2 eyes, 10 fingers
Average value group size = 6
Not perfect optimization for either eyes or fingers
Estimate is longer than reality for eyes
Estimate is shorter than reality for fingers
Remember the “too much data” feature/problem
![Page 20: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/20.jpg)
Composite Index
Like a sorted array
Can be ASC or DESC
But not ASC,DESC or DESC, ASC
(Image from Wikipedia)
![Page 21: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/21.jpg)
NULL and Equality
NULL = x is not true for ANY value of x
NULL = NULL is not true
If a referenced value in an equality is NULL
MySQL immediately returns false
![Page 22: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/22.jpg)
NULL and Equality
NULL-safe operator is <=>
No NULL-safe inequality operator
!(foo <=> bar)
Remember the “too much data” feature/problem
![Page 23: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/23.jpg)
NULL and Value Groups
Options - innodb_stats_method, myisam_stats_method
nulls_equal (default)
nulls_unequal
nulls_ignored
![Page 24: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/24.jpg)
PRIMARY Keys
Row identifiers
Cannot be NULL
InnoDB orders on disk in PRIMARY KEY order
![Page 25: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/25.jpg)
UNIQUE Keys
Row identifiers
Can be NULL
Both PRIMARY/UNIQUE can be composite index
![Page 26: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/26.jpg)
FOREIGN Keys
Parent/child relationship
e.g. payment->customer_id
Cascading update/deletes
![Page 27: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/27.jpg)
Numeric vs. Human-readable
customer_id status_id
121 1
122 2
125 1
status_id status1 free
2 paid
3 disabled
customer_id status121 free
122 paid
125 free
statusfree
paid
disabled
![Page 28: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/28.jpg)
Prefix Indexing
For strings
Up to 767 bytes on InnoDB, 1000 on MyISAM
Beware of charset!
![Page 29: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/29.jpg)
FULLTEXT Indexing
No prefix indexing
Only for CHAR, VARCHAR, TEXT
MyISAM only until MySQL 5.6
![Page 30: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/30.jpg)
GROUP BY and Sorting
By default, GROUP BY also sorts
May cause 'filesort' in EXPLAIN
ORDER BY NULL
If you do not care about the return order
![Page 31: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/31.jpg)
Knowing All This...
Use EXPLAIN
If you are not getting the index you expect
Check your expectations
Or file a bug: http://bugs.mysql.com
![Page 32: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/32.jpg)
How Do I Use EXPLAIN?
http://bit.ly/explainvideo
http://bit.ly/explainslides
![Page 33: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/33.jpg)
index_merge
On surface, looks good
Use more than one index
Better in MySQL 5.6
![Page 34: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/34.jpg)
index_merge before 5.6
Indicates you could make a better index
Index merge not used when it should have been– e.g. if range scan was possible
May have merged more indexes than necessary
![Page 35: Are You Getting the Best Out of Your MySQL Indexes? · Up to 767 bytes on InnoDB, 1000 on MyISAM Beware of charset! FULLTEXT Indexing No prefix indexing Only for CHAR, VARCHAR, TEXT](https://reader034.vdocuments.net/reader034/viewer/2022050507/5f98a441cceaa613500e4c24/html5/thumbnails/35.jpg)
Questions? Comments?OurSQL Podcast
www.oursql.com
MySQL Administrator's Bible
- tinyurl.com/mysqlbible
planet.mysql.com
mysqlmarinate.com