SlideShare a Scribd company logo
MYSQL PERFORMANCE
OPTIMIZATION
(MYSQL PRESTATIE-OPTIMALISATIE)
ALS JE DIT MOEST LEZEN, DAN BEN JE IN DE VERKEERDE KAMER… 
JOOMLADAY NETHERLANDS 2013
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 1
INTRODUCTION
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
INTRODUCTION
• Eli Aschkenasy
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
INTRODUCTION
• Eli Aschkenasy
• themodularway.com
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
INTRODUCTION
• Eli Aschkenasy
• themodularway.com
• Oracle certified (doesn’t really mean anything)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
INTRODUCTION
• Eli Aschkenasy
• themodularway.com
• Oracle certified (doesn’t really mean anything)
• GE sourcing database project
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
INTRODUCTION
• Eli Aschkenasy
• themodularway.com
• Oracle certified (doesn’t really mean anything)
• GE sourcing database project
• Agenda
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
AGENDA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
STRATEGIC OVERVIEW
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
STRATEGIC OVERVIEW
• Find smart people – Learn from them
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
STRATEGIC OVERVIEW
• Find smart people – Learn from them
• Find less knowledgeable people – Teach them (great design
benefits)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
STRATEGIC OVERVIEW
• Find smart people – Learn from them
• Find less knowledgeable people – Teach them (great design benefits)
• Talk to the business people! – Become their marketing specialist
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
STRATEGIC OVERVIEW
• Find smart people – Learn from them
• Find less knowledgeable people – Teach them (great design benefits)
• Talk to the business people! – Become their marketing specialist
• Benchmark – Do It !!!!!!!!!!
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
STRATEGIC OVERVIEW
• Find smart people – Learn from them
• Find less knowledgeable people – Teach them (great design benefits)
• Talk to the business people! – Become their marketing specialist
• Benchmark – Do It !!!!!!!!!!
• Decide early
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – STRATEGIC
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 6
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – STRATEGIC
• DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 6
InnoDB
• Transactional
• Hot (Online) Backup
• Crash Safe(er)
MyISAM
• Full-Text Indexing
• Compression
• Low(er) Space Consumption
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7
InnoDB
• Transactional
• Hot (Online) Backup
• Crash Safe(er)
MyISAM
• Full-Text Indexing
• Compression
• Low(er) Space Consumption
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7
• Always!
• Transactional
InnoDB
• Transactional
• Hot (Online) Backup
• Crash Safe(er)
MyISAM
• Full-Text Indexing
• Compression
• Low(er) Space Consumption
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7
• Always!
• Transactional
• Logging
• Read Only
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – STRATEGIC
• DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 8
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – STRATEGIC
• DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6
• Data Types (Numbers, Strings, Special)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 8
NUMBERS STRINGS SPECIAL
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
NUMBERS
INT(1) vs. INT(20) ? (trick question)
UNSIGNED vs. SIGNED
FLOAT isn’t accurate but fast
DECIMAL in MySQL<4.1 calculated
as FLOAT
DECIMAL needs additional byte to
store decimal point
Think if BIGINT could be used even
for precise calculations
(x*1’000’000)
PLEASE, PLEASE, use unsigned
integer as primary index. (we’ll
talk about it later again).
STRINGS SPECIAL
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
NUMBERS
INT(1) vs. INT(20) ? (trick question)
UNSIGNED vs. SIGNED
FLOAT isn’t accurate but fast
DECIMAL in MySQL<4.1 calculated
as FLOAT
DECIMAL needs additional byte to
store decimal point
Think if BIGINT could be used even
for precise calculations
(x*1’000’000)
PLEASE, PLEASE, use unsigned
integer as primary index. (we’ll
talk about it later again).
STRINGS
Use CHAR for fixed length columns
US States is the best example
State code are perfect for
TINYINT UNSIGNED
MD5 Hash values are
another good candidate for
CHAR usage
VARCHAR requires length byte!
VARCHAR allocates space in chunks
so don’t be overly generous
TEXT is problematic in SORTs
Trick: Use SUBSTRING(x, fixed) to
alleviate the problem
SPECIAL
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
NUMBERS
INT(1) vs. INT(20) ? (trick question)
UNSIGNED vs. SIGNED
FLOAT isn’t accurate but fast
DECIMAL in MySQL<4.1 calculated
as FLOAT
DECIMAL needs additional byte to
store decimal point
Think if BIGINT could be used even
for precise calculations
(x*1’000’000)
PLEASE, PLEASE, use unsigned
integer as primary index. (we’ll
talk about it later again).
STRINGS
Use CHAR for fixed length columns
US States is the best example
State code are perfect for
TINYINT UNSIGNED
MD5 Hash values are
another good candidate for
CHAR usage
VARCHAR requires length byte!
VARCHAR allocates space in chunks
so don’t be overly generous
TEXT is problematic in SORTs
Trick: Use SUBSTRING(x, fixed) to
alleviate the problem
SPECIAL
Avoid NULL if possible
Harder for MySQL to
optimize query
Use TIMESTAMP instead of DATETIME
Limit 2038
EST
TIMESTAMP uses less
space
(I hardly ever use TIMESTAMP…)
BIT (actually string form)
Don’t use ENUM or SET
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
CODE EXAMPLES - BIT
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 10
mysql> CREATE TABLE bittest(a bit(8));
mysql> INSERT INTO bittest VALUES(b'00111001');
mysql> SELECT a, a + 0 FROM bittest;
+------+-------+
| a | a + 0 |
+------+-------+
| 9 | 57 |
+------+-------+
CODE EXAMPLES - ENUM
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 11
mysql> CREATE TABLE enum_test(e ENUM('fish', 'apple', 'dog') NOT NULL);
mysql> INSERT INTO enum_test(e) VALUES('fish'), ('dog'), ('apple');
mysql> SELECT e + 0 FROM enum_test; mysql> SELECT e FROM enum_test ORDER
BY e;
+-------+
| e + 0 |
+-------+
| 1 |
| 3 |
| 2 |
+-------+
CODE EXAMPLES - ENUM
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 11
mysql> CREATE TABLE enum_test(e ENUM('fish', 'apple', 'dog') NOT NULL);
mysql> INSERT INTO enum_test(e) VALUES('fish'), ('dog'), ('apple');
mysql> SELECT e + 0 FROM enum_test; mysql> SELECT e FROM enum_test ORDER
BY e;
+-------+
| e + 0 |
+-------+
| 1 |
| 3 |
| 2 |
+-------+
+-------+
| e |
+-------+
| fish |
| apple |
| dog |
+-------+
CODE EXAMPLES – DATETIME NOT NULL
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 12
DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00‘
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 13
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – NORMALIZATION
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – NORMALIZATION
• Normalized data is non-redundant
(Text book says this is the best option)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
DESIGN CONSIDERATIONS
SCHEMA OPTIMIZATION – NORMALIZATION
• Normalized data is non-redundant
(Text book says this is the best option)
• Reality introduces de-normalization
Welcome to Summary and Cache Tables
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
CODE EXAMPLES – SUMMARY TABLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 15
mysql> CREATE TABLE msg_per_hr (
hr DATETIME NOT NULL,
cnt INT UNSIGNED NOT NULL,
PRIMARY KEY(hr)
);
mysql> SELECT SUM(cnt) FROM msg_per_hr stored 23
hour
WHERE hr BETWEEN CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 23 HOUR concat rounds
to nearest hr.
AND CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 1 HOUR;
mysql> SELECT COUNT(*) FROM message first hour
WHERE posted >= NOW() - INTERVAL 24 HOUR
AND posted < CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 23 HOUR;
mysql> SELECT COUNT(*) FROM message last hour
WHERE posted >= CONCAT(LEFT(NOW(), 14), '00:00');
CODE EXAMPLES – CACHE TABLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 16
mysql> DROP TABLE IF EXISTS my_cache_new, my_cache_old;
mysql> CREATE TABLE my_cache_new LIKE my_cache;
-- populate my_cache_new as desired
mysql> RENAME TABLE my_cache TO my_cache_old, my_cache_new TO my_cache;
CODE EXAMPLES – COUNTER TABLE
CONCURRENCY ISSUE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 17
mysql> CREATE TABLE hit_counter (
cnt INT UNSIGNED NOT NULL
) ENGINE=InnoDB;
mysql> UPDATE hit_counter SET cnt = cnt + 1;
mysql> SELECT cnt FROM hit_counter;
CODE EXAMPLES – COUNTER TABLE
CONCURRENCY SOLUTION
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 18
mysql> CREATE TABLE hit_counter (
slot TINYINT UNSIGNED NOT NULL PRIMARY KEY,
cnt INT UNSIGNED NOT NULL
) ENGINE=InnoDB;
mysql> INSERT INTO hit_counter VALUES
(0,0),
(1,0),
(2,0),
(3,0),
…
(99,0);
mysql> UPDATE hit_counter SET cnt = cnt + 1 WHERE slot = RAND() * 100;
mysql> SELECT SUM(cnt) FROM hit_counter;
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
INDEXING
HASH INDEX
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
INDEXING
HASH INDEX
• InnoDB creates adaptive hash indexes on frequent queries
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
INDEXING
HASH INDEX
• InnoDB creates adaptive hash indexes on frequent queries
• Main downside is that index doesn’t help sorting
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
INDEXING
HASH INDEX
• InnoDB creates adaptive hash indexes on frequent queries
• Main downside is that index doesn’t help sorting
• Hash indexes can’t speed up range queries (WHERE age > 18)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
INDEXING
HASH INDEX – HOW TO – INCLUDING HASH
COLLISION
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 21
mysql> SELECT id FROM url WHERE url="http://www.joomladagen.nl";
CREATE TABLE pseudohash (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
url VARCHAR(255) NOT NULL,
url_crc INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);
CREATE TRIGGER pseudohash_crc_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN
SET NEW.url_crc=crc32(NEW.url);
CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN
SET NEW.url_crc=crc32(NEW.url);
mysql> SELECT id FROM url WHERE url_crc=CRC32("http://www.joomladagen.nl") AND
url="http://www.joomladagen.nl";
INDEXING
INDEX PROBLEMS
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart
WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1);
SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6));
WHERE name = ‘Hans’;
CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity!
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
INDEXING
INDEX PROBLEMS
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart
WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1);
SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6));
WHERE name = ‘Hans’;
CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity!
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
SELECT cc FROM payment WHERE staff_id = 2 AND customer_id =
584;
INDEXING
INDEX PROBLEMS
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart
WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1);
SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6));
WHERE name = ‘Hans’;
CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity!
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
SELECT cc FROM payment WHERE staff_id = 2 AND customer_id =
584;
KEY(staff_id,customer_id) ?
INDEXING
INDEX PROBLEMS
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart
WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1);
SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6));
WHERE name = ‘Hans’;
CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity!
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
SELECT cc FROM payment WHERE staff_id = 2 AND customer_id =
584;
KEY(staff_id,customer_id) ?
SELECT SUM(staff_id = 2), SUM(customer_id = 584) FROM
paymentG
*************************** 1. row ***************************
SUM(staff_id = 2): 7992
SUM(customer_id = 584): 30
INDEXING
INDEX PROBLEMS
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22
SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart
WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1);
SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6));
WHERE name = ‘Hans’;
CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity!
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
SELECT cc FROM payment WHERE staff_id = 2 AND customer_id =
584;
KEY(staff_id,customer_id) ?
SELECT SUM(staff_id = 2), SUM(customer_id = 584) FROM
paymentG
*************************** 1. row ***************************
SUM(staff_id = 2): 7992
SUM(customer_id = 584): 30
ALTER TABLE payment ADD KEY(customer_id, staff_id);
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
MySQL can’t use added index if
primary index uses range criterion
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
MySQL can’t use added index if
primary index uses range criterion
KEY(sex, country)
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
MySQL can’t use added index if
primary index uses range criterion
KEY(sex, country)
NO Selectivity!!!
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
MySQL can’t use added index if
primary index uses range criterion
KEY(sex, country)
NO Selectivity!!!
KEY(sex, country)
Assumption: all searches will include sex
and most will include country
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
WHERE age BETWEEN 18 AND 25
ORDER BY rating ASC
MySQL can’t use added index if
primary index uses range criterion
KEY(sex, country)
NO Selectivity!!!
KEY(sex, country)
Assumption: all searches will include sex
and most will include country
Trick: AND sex IN('m', 'f')
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
(sex, country, age)
(sex, country, region, age)
(sex, country, region, city, age)
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
(sex, country, age)
(sex, country, region, age)
(sex, country, region, city, age)
Using the IN() trick, we can implement
just the
(sex, country, region, city, age) index.
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
(sex, country, age)
(sex, country, region, age)
(sex, country, region, city, age)
Using the IN() trick, we can implement
just the
(sex, country, region, city, age) index.
Why is age at end?
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
(sex, country, age)
(sex, country, region, age)
(sex, country, region, city, age)
Using the IN() trick, we can implement
just the
(sex, country, region, city, age) index.
Why is age at end?
Remember our range problem?
MySQL uses indexes from left to right
unit the first range query
Trick: Convert WHERE age BETWEEN 18 and 25
to
WHERE age IN(18,19,20,21,22,23,24,25)
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 25
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
SELECT age, country, …. , name FROM profiles
WHERE sex=‘F‘
ORDER BY rating
LIMIT 100000, 10;
Retrieving 100’010 rows, discarding
100’000
If data load per row is 15kb calculated data is
18.32Mb and we’re discarding 18.31Mb!
SELECT age, country, …. , name FROM profiles
INNER JOIN (
SELECT id FROM profiles
WHERE x.sex='M‘
ORDER BY rating LIMIT 100000, 10
) AS x
USING(id);
INDEXING
EXAMPLE
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 25
CREATE TABLE profile(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sex CHAR(1) NOT NULL,
age TINYINT NOT NULL,
country VARCHAR(255) NOT NULL,
region VARCHAR(255) NOT NULL DEFAULT ‘’,
city VARCHAR(255) NOT NULL DEFAULT ‘’,
color_hair VARCHAR(255) NOT NULL DEFAULT ‘’,
color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’,
name
…
…
rating TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY(id)
);
KEY(sex, rating)
SELECT age, country, …. , name FROM profiles
WHERE sex=‘F‘
ORDER BY rating
LIMIT 100000, 10;
Retrieving 100’010 rows, discarding
100’000
If data load per row is 15kb calculated data is
18.32Mb and we’re discarding 18.31Mb!
SELECT age, country, …. , name FROM profiles
INNER JOIN (
SELECT id FROM profiles
WHERE x.sex='M‘
ORDER BY rating LIMIT 100000, 10
) AS x
USING(id);
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 26
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
SELECT recipes.ingredient.* FROM recipes.ingredient
...
;
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
SELECT recipes.ingredient.* FROM recipes.ingredient
...
;
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
SELECT recipes.ingredient.* FROM recipes.ingredient
...
;
SELECT img, name, …, comment FROM
comments
WHERE user_id = 123983;
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
SELECT recipes.ingredient.* FROM recipes.ingredient
...
;
SELECT img, name, …, comment FROM
comments
WHERE user_id = 123983;
What, did the image and name change
in the last 2microseconds?!?
QUERY OPTIMIZATION
TOO MUCH DATA
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27
SELECT * FROM Orgchart
WHERE lft - rgt = 1;
SELECT * FROM recipes.ingredient
INNER JOIN recipes.recipe_ingredient
USING(ingredient_id)
INNER JOIN recipes.recipe USING(recipe_id)
WHERE recipes.recipe.name = ‘Stroopwafel';
All I want is the ingredients for a Stroopwafel
This Query returns all columns for all three tables!
SELECT recipes.ingredient.* FROM recipes.ingredient
...
;
SELECT img, name, …, comment FROM
comments
WHERE user_id = 123983;
What, did the image and name change
in the last 2microseconds?!?
SELECT img, name, …, FROM comments
WHERE user_id = 123983;
SELECT comment FROM comments
WHERE user_id = 123983;
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28
DELETE FROM messages
WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28
DELETE FROM messages
WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);
<?php
…
$rows_affected = 0;
do {
$rows_affected = do_query("
DELETE FROM messages
WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH)
LIMIT 10000
");
} while $rows_affected > 0;
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
WHY? DENORMALIZED ?!?
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
WHY? DENORMALIZED ?!?
• Query cache validation of 3 tables instead of one
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
WHY? DENORMALIZED ?!?
• Query cache validation of 3 tables instead of one
• Lock contention (?)
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
WHY? DENORMALIZED ?!?
• Query cache validation of 3 tables instead of one
• Lock contention (?)
• Query index lookup of IN() is better than with JOINS
QUERY OPTIMIZATION
DIVIDE AND CONQUER
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag=‘joomladagen';
SELECT * FROM tag WHERE tag='joomladagen';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
WHY? DENORMALIZED ?!?
• Query cache validation of 3 tables instead of one
• Lock contention (?)
• Query index lookup of IN() is better than with JOINS
• Potential for application caching
AGENDA
• Introduction (5min)
• Strategic Overview (5min)
• Design Considerations – Schema Optimization – Strategic (10min)
• Design Considerations – Schema Optimization – Normalization
(10min hopefully)
• Indexing (5min)
• Query Optimization (10min)
JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 30

More Related Content

Similar to MySQL Performance Optimization #JDNL13

Hidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
Hidden Treasures in Google Analytics - SMX East 2011 - Adam WareHidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
Hidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
SwellPath
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dave Stokes
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Dave Stokes
 
MySQL Performance Tuning 101 (Bahasa)
MySQL Performance Tuning 101 (Bahasa)MySQL Performance Tuning 101 (Bahasa)
MySQL Performance Tuning 101 (Bahasa)
OracleMySQL
 
Operationalizing analytics to scale
Operationalizing analytics to scaleOperationalizing analytics to scale
Operationalizing analytics to scale
Looker
 
PowerApps deep dive
PowerApps deep divePowerApps deep dive
PowerApps deep dive
Timo Pertilä
 
SEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
SEMrush- 5 Hours of SEO - Scaling Ranking Data AnalysisSEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
SEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
Alexis Sanders
 
Confoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & HistogramsConfoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & Histograms
Dave Stokes
 
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
Semrush
 
SQL Tutorial for Marketers
SQL Tutorial for MarketersSQL Tutorial for Marketers
SQL Tutorial for Marketers
Justin Mares
 
Tactical Data Science Tips: Python and Spark Together
Tactical Data Science Tips: Python and Spark TogetherTactical Data Science Tips: Python and Spark Together
Tactical Data Science Tips: Python and Spark Together
Databricks
 
Oracle CBO Fundamental
Oracle CBO FundamentalOracle CBO Fundamental
Oracle CBO Fundamental
JAEGEUN YU
 
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
Jim Czuprynski
 
Scale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done RightScale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done Right
Fred Moyer
 
Dan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New FeaturesDan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New Features
Embarcadero Technologies
 
Unlock the value in your big data reservoir using oracle big data discovery a...
Unlock the value in your big data reservoir using oracle big data discovery a...Unlock the value in your big data reservoir using oracle big data discovery a...
Unlock the value in your big data reservoir using oracle big data discovery a...
Mark Rittman
 
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
Harry McLaren
 
Find Anything In Your APEX App - Fuzzy Search with Oracle Text
Find Anything In Your APEX App - Fuzzy Search with Oracle TextFind Anything In Your APEX App - Fuzzy Search with Oracle Text
Find Anything In Your APEX App - Fuzzy Search with Oracle Text
Carsten Czarski
 
Fuzzing - A Tale of Two Cultures
Fuzzing - A Tale of Two CulturesFuzzing - A Tale of Two Cultures
Fuzzing - A Tale of Two Cultures
CISPA Helmholtz Center for Information Security
 
Cincom Smalltalk 2018 Roadmap
Cincom Smalltalk 2018 RoadmapCincom Smalltalk 2018 Roadmap
Cincom Smalltalk 2018 Roadmap
ESUG
 

Similar to MySQL Performance Optimization #JDNL13 (20)

Hidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
Hidden Treasures in Google Analytics - SMX East 2011 - Adam WareHidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
Hidden Treasures in Google Analytics - SMX East 2011 - Adam Ware
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
 
MySQL Performance Tuning 101 (Bahasa)
MySQL Performance Tuning 101 (Bahasa)MySQL Performance Tuning 101 (Bahasa)
MySQL Performance Tuning 101 (Bahasa)
 
Operationalizing analytics to scale
Operationalizing analytics to scaleOperationalizing analytics to scale
Operationalizing analytics to scale
 
PowerApps deep dive
PowerApps deep divePowerApps deep dive
PowerApps deep dive
 
SEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
SEMrush- 5 Hours of SEO - Scaling Ranking Data AnalysisSEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
SEMrush- 5 Hours of SEO - Scaling Ranking Data Analysis
 
Confoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & HistogramsConfoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & Histograms
 
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
Alexis Sanders — Scaling Ranking Data Analysis: Organizing, Visualizing, and ...
 
SQL Tutorial for Marketers
SQL Tutorial for MarketersSQL Tutorial for Marketers
SQL Tutorial for Marketers
 
Tactical Data Science Tips: Python and Spark Together
Tactical Data Science Tips: Python and Spark TogetherTactical Data Science Tips: Python and Spark Together
Tactical Data Science Tips: Python and Spark Together
 
Oracle CBO Fundamental
Oracle CBO FundamentalOracle CBO Fundamental
Oracle CBO Fundamental
 
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
What's Your Super-Power? Mine is Machine Learning with Oracle Autonomous DB.
 
Scale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done RightScale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done Right
 
Dan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New FeaturesDan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New Features
 
Unlock the value in your big data reservoir using oracle big data discovery a...
Unlock the value in your big data reservoir using oracle big data discovery a...Unlock the value in your big data reservoir using oracle big data discovery a...
Unlock the value in your big data reservoir using oracle big data discovery a...
 
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
Using Metrics for Fun, Developing with the KV Store + Javascript & News from ...
 
Find Anything In Your APEX App - Fuzzy Search with Oracle Text
Find Anything In Your APEX App - Fuzzy Search with Oracle TextFind Anything In Your APEX App - Fuzzy Search with Oracle Text
Find Anything In Your APEX App - Fuzzy Search with Oracle Text
 
Fuzzing - A Tale of Two Cultures
Fuzzing - A Tale of Two CulturesFuzzing - A Tale of Two Cultures
Fuzzing - A Tale of Two Cultures
 
Cincom Smalltalk 2018 Roadmap
Cincom Smalltalk 2018 RoadmapCincom Smalltalk 2018 Roadmap
Cincom Smalltalk 2018 Roadmap
 

Recently uploaded

一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
Project Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdfProject Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdf
Karya Keeper
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
ShulagnaSarkar2
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
dakas1
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
kalichargn70th171
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
Rakesh Kumar R
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
TaghreedAltamimi
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
safelyiotech
 
YAML crash COURSE how to write yaml file for adding configuring details
YAML crash COURSE how to write yaml file for adding configuring detailsYAML crash COURSE how to write yaml file for adding configuring details
YAML crash COURSE how to write yaml file for adding configuring details
NishanthaBulumulla1
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 

Recently uploaded (20)

一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
Project Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdfProject Management: The Role of Project Dashboards.pdf
Project Management: The Role of Project Dashboards.pdf
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
The Key to Digital Success_ A Comprehensive Guide to Continuous Testing Integ...
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
 
YAML crash COURSE how to write yaml file for adding configuring details
YAML crash COURSE how to write yaml file for adding configuring detailsYAML crash COURSE how to write yaml file for adding configuring details
YAML crash COURSE how to write yaml file for adding configuring details
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 

MySQL Performance Optimization #JDNL13

  • 1. MYSQL PERFORMANCE OPTIMIZATION (MYSQL PRESTATIE-OPTIMALISATIE) ALS JE DIT MOEST LEZEN, DAN BEN JE IN DE VERKEERDE KAMER…  JOOMLADAY NETHERLANDS 2013 JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 1
  • 2. INTRODUCTION JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 3. INTRODUCTION • Eli Aschkenasy JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 4. INTRODUCTION • Eli Aschkenasy • themodularway.com JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 5. INTRODUCTION • Eli Aschkenasy • themodularway.com • Oracle certified (doesn’t really mean anything) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 6. INTRODUCTION • Eli Aschkenasy • themodularway.com • Oracle certified (doesn’t really mean anything) • GE sourcing database project JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 7. INTRODUCTION • Eli Aschkenasy • themodularway.com • Oracle certified (doesn’t really mean anything) • GE sourcing database project • Agenda JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 2
  • 8. AGENDA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 9. AGENDA • Introduction (5min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 10. AGENDA • Introduction (5min) • Strategic Overview (5min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 11. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 12. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 13. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 14. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 3
  • 15. STRATEGIC OVERVIEW JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 16. STRATEGIC OVERVIEW • Find smart people – Learn from them JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 17. STRATEGIC OVERVIEW • Find smart people – Learn from them • Find less knowledgeable people – Teach them (great design benefits) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 18. STRATEGIC OVERVIEW • Find smart people – Learn from them • Find less knowledgeable people – Teach them (great design benefits) • Talk to the business people! – Become their marketing specialist JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 19. STRATEGIC OVERVIEW • Find smart people – Learn from them • Find less knowledgeable people – Teach them (great design benefits) • Talk to the business people! – Become their marketing specialist • Benchmark – Do It !!!!!!!!!! JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 20. STRATEGIC OVERVIEW • Find smart people – Learn from them • Find less knowledgeable people – Teach them (great design benefits) • Talk to the business people! – Become their marketing specialist • Benchmark – Do It !!!!!!!!!! • Decide early JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 4
  • 21. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 5
  • 22. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – STRATEGIC JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 6
  • 23. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – STRATEGIC • DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6 JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 6
  • 24. InnoDB • Transactional • Hot (Online) Backup • Crash Safe(er) MyISAM • Full-Text Indexing • Compression • Low(er) Space Consumption JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7
  • 25. InnoDB • Transactional • Hot (Online) Backup • Crash Safe(er) MyISAM • Full-Text Indexing • Compression • Low(er) Space Consumption JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7 • Always! • Transactional
  • 26. InnoDB • Transactional • Hot (Online) Backup • Crash Safe(er) MyISAM • Full-Text Indexing • Compression • Low(er) Space Consumption JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 7 • Always! • Transactional • Logging • Read Only
  • 27. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – STRATEGIC • DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6 JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 8
  • 28. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – STRATEGIC • DB Engines (InnoDB vs. MyISAM) – not including MySQL 5.6 • Data Types (Numbers, Strings, Special) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 8
  • 29. NUMBERS STRINGS SPECIAL JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
  • 30. NUMBERS INT(1) vs. INT(20) ? (trick question) UNSIGNED vs. SIGNED FLOAT isn’t accurate but fast DECIMAL in MySQL<4.1 calculated as FLOAT DECIMAL needs additional byte to store decimal point Think if BIGINT could be used even for precise calculations (x*1’000’000) PLEASE, PLEASE, use unsigned integer as primary index. (we’ll talk about it later again). STRINGS SPECIAL JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
  • 31. NUMBERS INT(1) vs. INT(20) ? (trick question) UNSIGNED vs. SIGNED FLOAT isn’t accurate but fast DECIMAL in MySQL<4.1 calculated as FLOAT DECIMAL needs additional byte to store decimal point Think if BIGINT could be used even for precise calculations (x*1’000’000) PLEASE, PLEASE, use unsigned integer as primary index. (we’ll talk about it later again). STRINGS Use CHAR for fixed length columns US States is the best example State code are perfect for TINYINT UNSIGNED MD5 Hash values are another good candidate for CHAR usage VARCHAR requires length byte! VARCHAR allocates space in chunks so don’t be overly generous TEXT is problematic in SORTs Trick: Use SUBSTRING(x, fixed) to alleviate the problem SPECIAL JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
  • 32. NUMBERS INT(1) vs. INT(20) ? (trick question) UNSIGNED vs. SIGNED FLOAT isn’t accurate but fast DECIMAL in MySQL<4.1 calculated as FLOAT DECIMAL needs additional byte to store decimal point Think if BIGINT could be used even for precise calculations (x*1’000’000) PLEASE, PLEASE, use unsigned integer as primary index. (we’ll talk about it later again). STRINGS Use CHAR for fixed length columns US States is the best example State code are perfect for TINYINT UNSIGNED MD5 Hash values are another good candidate for CHAR usage VARCHAR requires length byte! VARCHAR allocates space in chunks so don’t be overly generous TEXT is problematic in SORTs Trick: Use SUBSTRING(x, fixed) to alleviate the problem SPECIAL Avoid NULL if possible Harder for MySQL to optimize query Use TIMESTAMP instead of DATETIME Limit 2038 EST TIMESTAMP uses less space (I hardly ever use TIMESTAMP…) BIT (actually string form) Don’t use ENUM or SET JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 9
  • 33. CODE EXAMPLES - BIT JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 10 mysql> CREATE TABLE bittest(a bit(8)); mysql> INSERT INTO bittest VALUES(b'00111001'); mysql> SELECT a, a + 0 FROM bittest; +------+-------+ | a | a + 0 | +------+-------+ | 9 | 57 | +------+-------+
  • 34. CODE EXAMPLES - ENUM JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 11 mysql> CREATE TABLE enum_test(e ENUM('fish', 'apple', 'dog') NOT NULL); mysql> INSERT INTO enum_test(e) VALUES('fish'), ('dog'), ('apple'); mysql> SELECT e + 0 FROM enum_test; mysql> SELECT e FROM enum_test ORDER BY e; +-------+ | e + 0 | +-------+ | 1 | | 3 | | 2 | +-------+
  • 35. CODE EXAMPLES - ENUM JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 11 mysql> CREATE TABLE enum_test(e ENUM('fish', 'apple', 'dog') NOT NULL); mysql> INSERT INTO enum_test(e) VALUES('fish'), ('dog'), ('apple'); mysql> SELECT e + 0 FROM enum_test; mysql> SELECT e FROM enum_test ORDER BY e; +-------+ | e + 0 | +-------+ | 1 | | 3 | | 2 | +-------+ +-------+ | e | +-------+ | fish | | apple | | dog | +-------+
  • 36. CODE EXAMPLES – DATETIME NOT NULL JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 12 DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00‘
  • 37. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 13
  • 38. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – NORMALIZATION JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
  • 39. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – NORMALIZATION • Normalized data is non-redundant (Text book says this is the best option) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
  • 40. DESIGN CONSIDERATIONS SCHEMA OPTIMIZATION – NORMALIZATION • Normalized data is non-redundant (Text book says this is the best option) • Reality introduces de-normalization Welcome to Summary and Cache Tables JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 14
  • 41. CODE EXAMPLES – SUMMARY TABLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 15 mysql> CREATE TABLE msg_per_hr ( hr DATETIME NOT NULL, cnt INT UNSIGNED NOT NULL, PRIMARY KEY(hr) ); mysql> SELECT SUM(cnt) FROM msg_per_hr stored 23 hour WHERE hr BETWEEN CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 23 HOUR concat rounds to nearest hr. AND CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 1 HOUR; mysql> SELECT COUNT(*) FROM message first hour WHERE posted >= NOW() - INTERVAL 24 HOUR AND posted < CONCAT(LEFT(NOW(), 14), '00:00') - INTERVAL 23 HOUR; mysql> SELECT COUNT(*) FROM message last hour WHERE posted >= CONCAT(LEFT(NOW(), 14), '00:00');
  • 42. CODE EXAMPLES – CACHE TABLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 16 mysql> DROP TABLE IF EXISTS my_cache_new, my_cache_old; mysql> CREATE TABLE my_cache_new LIKE my_cache; -- populate my_cache_new as desired mysql> RENAME TABLE my_cache TO my_cache_old, my_cache_new TO my_cache;
  • 43. CODE EXAMPLES – COUNTER TABLE CONCURRENCY ISSUE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 17 mysql> CREATE TABLE hit_counter ( cnt INT UNSIGNED NOT NULL ) ENGINE=InnoDB; mysql> UPDATE hit_counter SET cnt = cnt + 1; mysql> SELECT cnt FROM hit_counter;
  • 44. CODE EXAMPLES – COUNTER TABLE CONCURRENCY SOLUTION JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 18 mysql> CREATE TABLE hit_counter ( slot TINYINT UNSIGNED NOT NULL PRIMARY KEY, cnt INT UNSIGNED NOT NULL ) ENGINE=InnoDB; mysql> INSERT INTO hit_counter VALUES (0,0), (1,0), (2,0), (3,0), … (99,0); mysql> UPDATE hit_counter SET cnt = cnt + 1 WHERE slot = RAND() * 100; mysql> SELECT SUM(cnt) FROM hit_counter;
  • 45. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 19
  • 46. INDEXING HASH INDEX JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
  • 47. INDEXING HASH INDEX • InnoDB creates adaptive hash indexes on frequent queries JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
  • 48. INDEXING HASH INDEX • InnoDB creates adaptive hash indexes on frequent queries • Main downside is that index doesn’t help sorting JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
  • 49. INDEXING HASH INDEX • InnoDB creates adaptive hash indexes on frequent queries • Main downside is that index doesn’t help sorting • Hash indexes can’t speed up range queries (WHERE age > 18) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 20
  • 50. INDEXING HASH INDEX – HOW TO – INCLUDING HASH COLLISION JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 21 mysql> SELECT id FROM url WHERE url="http://www.joomladagen.nl"; CREATE TABLE pseudohash ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, url VARCHAR(255) NOT NULL, url_crc INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY(id) ); CREATE TRIGGER pseudohash_crc_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN SET NEW.url_crc=crc32(NEW.url); CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN SET NEW.url_crc=crc32(NEW.url); mysql> SELECT id FROM url WHERE url_crc=CRC32("http://www.joomladagen.nl") AND url="http://www.joomladagen.nl";
  • 51. INDEXING INDEX PROBLEMS JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22 SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1); SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6)); WHERE name = ‘Hans’; CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity! c1 INT, c2 INT, c3 INT, KEY(c1), KEY(c2), KEY(c3) );
  • 52. INDEXING INDEX PROBLEMS JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22 SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1); SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6)); WHERE name = ‘Hans’; CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity! c1 INT, c2 INT, c3 INT, KEY(c1), KEY(c2), KEY(c3) ); SELECT cc FROM payment WHERE staff_id = 2 AND customer_id = 584;
  • 53. INDEXING INDEX PROBLEMS JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22 SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1); SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6)); WHERE name = ‘Hans’; CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity! c1 INT, c2 INT, c3 INT, KEY(c1), KEY(c2), KEY(c3) ); SELECT cc FROM payment WHERE staff_id = 2 AND customer_id = 584; KEY(staff_id,customer_id) ?
  • 54. INDEXING INDEX PROBLEMS JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22 SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1); SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6)); WHERE name = ‘Hans’; CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity! c1 INT, c2 INT, c3 INT, KEY(c1), KEY(c2), KEY(c3) ); SELECT cc FROM payment WHERE staff_id = 2 AND customer_id = 584; KEY(staff_id,customer_id) ? SELECT SUM(staff_id = 2), SUM(customer_id = 584) FROM paymentG *************************** 1. row *************************** SUM(staff_id = 2): 7992 SUM(customer_id = 584): 30
  • 55. INDEXING INDEX PROBLEMS JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 22 SELECT * FROM Orgchart SELECT a, c FROM Orgchart SELECT a, c FROM Orgchart WHERE lft - rgt = 1; WHERE lft - rgt = 1; WHERE lft =(rgt – 1); SELECT name FROM people mysql> ALTER TABLE people ADD KEY (idx_name(6)); WHERE name = ‘Hans’; CREATE TABLE t ( KEY(c1,c2,c3) ? KEY(c1,c3) Specificity! c1 INT, c2 INT, c3 INT, KEY(c1), KEY(c2), KEY(c3) ); SELECT cc FROM payment WHERE staff_id = 2 AND customer_id = 584; KEY(staff_id,customer_id) ? SELECT SUM(staff_id = 2), SUM(customer_id = 584) FROM paymentG *************************** 1. row *************************** SUM(staff_id = 2): 7992 SUM(customer_id = 584): 30 ALTER TABLE payment ADD KEY(customer_id, staff_id);
  • 56. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) );
  • 57. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC
  • 58. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC MySQL can’t use added index if primary index uses range criterion
  • 59. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC MySQL can’t use added index if primary index uses range criterion KEY(sex, country)
  • 60. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC MySQL can’t use added index if primary index uses range criterion KEY(sex, country) NO Selectivity!!!
  • 61. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC MySQL can’t use added index if primary index uses range criterion KEY(sex, country) NO Selectivity!!! KEY(sex, country) Assumption: all searches will include sex and most will include country
  • 62. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 23 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); WHERE age BETWEEN 18 AND 25 ORDER BY rating ASC MySQL can’t use added index if primary index uses range criterion KEY(sex, country) NO Selectivity!!! KEY(sex, country) Assumption: all searches will include sex and most will include country Trick: AND sex IN('m', 'f')
  • 63. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) );
  • 64. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); (sex, country, age) (sex, country, region, age) (sex, country, region, city, age)
  • 65. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); (sex, country, age) (sex, country, region, age) (sex, country, region, city, age) Using the IN() trick, we can implement just the (sex, country, region, city, age) index.
  • 66. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); (sex, country, age) (sex, country, region, age) (sex, country, region, city, age) Using the IN() trick, we can implement just the (sex, country, region, city, age) index. Why is age at end?
  • 67. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 24 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); (sex, country, age) (sex, country, region, age) (sex, country, region, city, age) Using the IN() trick, we can implement just the (sex, country, region, city, age) index. Why is age at end? Remember our range problem? MySQL uses indexes from left to right unit the first range query Trick: Convert WHERE age BETWEEN 18 and 25 to WHERE age IN(18,19,20,21,22,23,24,25)
  • 68. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 25 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); SELECT age, country, …. , name FROM profiles WHERE sex=‘F‘ ORDER BY rating LIMIT 100000, 10; Retrieving 100’010 rows, discarding 100’000 If data load per row is 15kb calculated data is 18.32Mb and we’re discarding 18.31Mb! SELECT age, country, …. , name FROM profiles INNER JOIN ( SELECT id FROM profiles WHERE x.sex='M‘ ORDER BY rating LIMIT 100000, 10 ) AS x USING(id);
  • 69. INDEXING EXAMPLE JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 25 CREATE TABLE profile( id INT UNSIGNED NOT NULL AUTO_INCREMENT, sex CHAR(1) NOT NULL, age TINYINT NOT NULL, country VARCHAR(255) NOT NULL, region VARCHAR(255) NOT NULL DEFAULT ‘’, city VARCHAR(255) NOT NULL DEFAULT ‘’, color_hair VARCHAR(255) NOT NULL DEFAULT ‘’, color_eyes VARCHAR(255) NOT NULL DEFAULT ‘’, name … … rating TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(id) ); KEY(sex, rating) SELECT age, country, …. , name FROM profiles WHERE sex=‘F‘ ORDER BY rating LIMIT 100000, 10; Retrieving 100’010 rows, discarding 100’000 If data load per row is 15kb calculated data is 18.32Mb and we’re discarding 18.31Mb! SELECT age, country, …. , name FROM profiles INNER JOIN ( SELECT id FROM profiles WHERE x.sex='M‘ ORDER BY rating LIMIT 100000, 10 ) AS x USING(id);
  • 70. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 26
  • 71. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1;
  • 72. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1;
  • 73. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel';
  • 74. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables!
  • 75. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables! SELECT recipes.ingredient.* FROM recipes.ingredient ... ;
  • 76. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables! SELECT recipes.ingredient.* FROM recipes.ingredient ... ;
  • 77. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables! SELECT recipes.ingredient.* FROM recipes.ingredient ... ; SELECT img, name, …, comment FROM comments WHERE user_id = 123983;
  • 78. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables! SELECT recipes.ingredient.* FROM recipes.ingredient ... ; SELECT img, name, …, comment FROM comments WHERE user_id = 123983; What, did the image and name change in the last 2microseconds?!?
  • 79. QUERY OPTIMIZATION TOO MUCH DATA JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 27 SELECT * FROM Orgchart WHERE lft - rgt = 1; SELECT * FROM recipes.ingredient INNER JOIN recipes.recipe_ingredient USING(ingredient_id) INNER JOIN recipes.recipe USING(recipe_id) WHERE recipes.recipe.name = ‘Stroopwafel'; All I want is the ingredients for a Stroopwafel This Query returns all columns for all three tables! SELECT recipes.ingredient.* FROM recipes.ingredient ... ; SELECT img, name, …, comment FROM comments WHERE user_id = 123983; What, did the image and name change in the last 2microseconds?!? SELECT img, name, …, FROM comments WHERE user_id = 123983; SELECT comment FROM comments WHERE user_id = 123983;
  • 80. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28
  • 81. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28 DELETE FROM messages WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);
  • 82. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 28 DELETE FROM messages WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH); <?php … $rows_affected = 0; do { $rows_affected = do_query(" DELETE FROM messages WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH) LIMIT 10000 "); } while $rows_affected > 0;
  • 83. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29
  • 84. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen';
  • 85. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904);
  • 86. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904); WHY? DENORMALIZED ?!?
  • 87. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904); WHY? DENORMALIZED ?!? • Query cache validation of 3 tables instead of one
  • 88. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904); WHY? DENORMALIZED ?!? • Query cache validation of 3 tables instead of one • Lock contention (?)
  • 89. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904); WHY? DENORMALIZED ?!? • Query cache validation of 3 tables instead of one • Lock contention (?) • Query index lookup of IN() is better than with JOINS
  • 90. QUERY OPTIMIZATION DIVIDE AND CONQUER JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 29 SELECT * FROM tag JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag=‘joomladagen'; SELECT * FROM tag WHERE tag='joomladagen'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN(123,456,567,9098,8904); WHY? DENORMALIZED ?!? • Query cache validation of 3 tables instead of one • Lock contention (?) • Query index lookup of IN() is better than with JOINS • Potential for application caching
  • 91. AGENDA • Introduction (5min) • Strategic Overview (5min) • Design Considerations – Schema Optimization – Strategic (10min) • Design Considerations – Schema Optimization – Normalization (10min hopefully) • Indexing (5min) • Query Optimization (10min) JOOMLADAY NETHERLANDS 2013 - ELI ASCHKENASY - @ELIASCHKENASY 30