Pingu
Computer MySQL PostgreSQL Books Publications
Spielereien Kanu Business TopoDB POI Klettersteigen History TransPool Thermal Baden Brokenstuben Goldwaschen
Blog Contact
Shinguz
Google
/ch/open

MariaDB and MySQL work

/ home / computer / .

MariaDB / MySQL - Optimizer

Analyze

Optimize

Execute

Optimizer tests

CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  i_ui INT UNSIGNED NULL,
  i_ni INT UNSIGNED NULL,
  dt_i DATETIME,
  dt_ni DATETIME,
  s_i VARCHAR(255),
  s_ni VARCHAR(255),
  PRIMARY KEY (`id`),
  UNIQUE INDEX (i_ui),
  INDEX (dt_i),
  INDEX (s_i)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
;

INSERT INTO test SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL
FROM test;
-- 1M rows

SELECT MAX(id) INTO @max FROM test;
UPDATE test SET i_ui = @max - id, i_ni  = @max, dt_i = DATE_ADD(NOW(), INTERVAL id SECOND), dt_ni = DATE_ADD(NOW(), INTERVAL id SECOND), s_i = CONCAT('Some text ', id), s_ni = CONCAT('Some text ', id);

-- Primary Key access
SQL> EXPLAIN SELECT * FROM test WHERE id = 42;
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id   | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|    1 | SIMPLE      | test  | const | PRIMARY       | PRIMARY | 4       | const | 1    |       |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+

-- Unique Key access
SQL> EXPLAIN SELECT * FROM test WHERE i_ui = 42;
+------+-------------+-------+-------+---------------+------+---------+-------+------+-------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref   | rows | Extra |
+------+-------------+-------+-------+---------------+------+---------+-------+------+-------+
|    1 | SIMPLE      | test  | const | i_ui          | i_ui | 5       | const | 1    |       |
+------+-------------+-------+-------+---------------+------+---------+-------+------+-------+

-- Secondary Key access
SQL> EXPLAIN SELECT * FROM test WHERE s_i = 'Some text 1000042';
+------+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra                 |
+------+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+
|    1 | SIMPLE      | test  | ref  | s_i           | s_i  | 1023    | const | 1    | Using index condition |
+------+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+

-- Non indexed column access
SQL> EXPLAIN SELECT * FROM test WHERE i_ni = 42;
+------+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+------+-------------+-------+------+---------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | test  | ALL  | NULL          | NULL | NULL    | NULL | 1063513 | Using where |
+------+-------------+-------+------+---------------+------+---------+------+---------+-------------+

-- Secondary index range access
SQL> EXPLAIN SELECT * FROM test WHERE i_ui BETWEEN 10 AND 42;
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                 |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
|    1 | SIMPLE      | test  | range | i_ui          | i_ui | 5       | NULL | 33   | Using index condition |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

-- Secondary index LIKE access
SQL> EXPLAIN SELECT * FROM test WHERE s_i LIKE 'Some text 10000%';
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                 |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
|    1 | SIMPLE      | test  | range | s_i           | s_i  | 1023    | NULL | 101  | Using index condition |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

-- Index full scan on Primary Key
SQL> EXPLAIN SELECT id FROM test;
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | test  | index | NULL          | i_ui | 5       | NULL | 1063513 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
-- It does a index full scan on a secondary key!

-- Index range scan on Primary Key
SQL> EXPLAIN SELECT id FROM test WHERE id between 100 and 1000;
+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|    1 | SIMPLE      | test  | range | PRIMARY       | PRIMARY | 4       | NULL | 448  | Using where |
+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
-- It does a range scan on the Primary Key


-- Forcing a range scan on secondary key
SQL> EXPLAIN SELECT id FROM test USE INDEX (i_ui) WHERE id between 100 and 1000;
+------+-------------+-------+-------+---------------+------+---------+------+---------+--------------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows    | Extra                    |
+------+-------------+-------+-------+---------------+------+---------+------+---------+--------------------------+
|    1 | SIMPLE      | test  | index | NULL          | i_ui | 5       | NULL | 1063513 | Using where; Using index |
+------+-------------+-------+-------+---------------+------+---------+------+---------+--------------------------+
-- Somehow it seems not capable to short cut here!!!

-- Index full scan on Secondary Key
SQL> EXPLAIN SELECT i_ui FROM test;
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | test  | index | NULL          | i_ui | 5       | NULL | 1063513 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+


-- Index range scan on Secondary Key
SQL> EXPLAIN SELECT i_ui FROM test WHERE i_ui between 100 and 1000;
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|    1 | SIMPLE      | test  | range | i_ui          | i_ui | 5       | NULL | 901  | Using where; Using index |
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+

-- Index range scan on a covering index
SQL> EXPLAIN SELECT id from test WHERE i_ui between 100 and 1000;
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|    1 | SIMPLE      | test  | range | i_ui          | i_ui | 5       | NULL | 901  | Using where; Using index |
+------+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+