5分鐘瞭解MySQL/MariaDB新特性之索引下推優化

wKioL1f-3yuQOVJpAAA4eVx2Dz8354.jpg

wKiom1f-3yuwEnYaAAA4pG6yXEQ066.jpg

MySQL/MariaDB新特性之索引下推優化

索引下推優化

Part1:index_condition_pushdownmysql

index_condition_pushdown(ICP)默認開啓,能夠經過命令:sql

show variables like 'optimizer_switch'\G來查看,以下圖所示:數據庫

wKioL1f-4OCykRzoAAFF6MDxE5E868.jpg



Part2:原理簡述這一特性從MariaDB5.3/MySQL5.6起,開始生效,咱們在執行查詢計劃的時候,看到的Using index condition特性,簡稱爲ICP。它能夠提升檢索速度,提升從server層到存儲引擎層的調用速度,並減小了存儲引擎訪問表的次數,從而提升了數據庫的總體性能。總之一句話,當你看到執行計劃中出現了using index condition的時候,說明效率好!很好!很是好!就對了~
ide


實戰

Part1:ICP在MySQL5.6.25下的表現性能

[root@HE1 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.25-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.25-log |
+------------+
1 row in set (0.00 sec)
mysql> use helei;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show create table helei_stu\G\
*************************** 1. row ***************************
       Table: helei_stu
Create Table: CREATE TABLE `helei_stu` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL DEFAULT '',
  `class` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `score` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_class_score` (`class`,`score`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> explain select * from helei_stu where class=2 and score >60;
+----+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| id | select_type | table     | type  | possible_keys   | key             | key_len | ref  | rows | Extra                 |
+----+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
|  1 | SIMPLE      | helei_stu | range | idx_class_score | idx_class_score | 2       | NULL |    8 | Using index condition |
+----+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
1 row in set (0.04 sec)

能夠看出,在MySQL5.6.25中,執行結果以下圖所示:優化

wKiom1f-5teQaJa1AAFDPQKBVXU512.jpg



Part2:ICP在MySQL5.7.15下的表現ui

[root@HE1 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 5.7.15-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select version();
+------------+
| version()  |
+------------+
| 5.7.15-log |
+------------+
1 row in set (0.00 sec)
mysql> show create table helei_stu\G
*************************** 1. row ***************************
       Table: helei_stu
Create Table: CREATE TABLE `helei_stu` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL DEFAULT '',
  `class` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `score` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_class_score` (`class`,`score`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> explain select * from helei_stu where class=2 and score >60;                                                                                          
+----+-------------+-----------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
| id | select_type | table     | partitions | type  | possible_keys   | key             | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-----------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | helei_stu | NULL       | range | idx_class_score | idx_class_score | 2       | NULL |    8 |   100.00 | Using index condition |
+----+-------------+-----------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

能夠看出,在MySQL5.7.15中,執行結果以下圖所示:
this

wKioL1f-44azrQ5lAAFa1KSgEH4702.jpg




Part3:ICP在MariaDB10.1.16下的表現spa

[root@HE3 ~]# /usr/local/mariadb/bin/mysql -uroot -S /tmp/mariadb.sock 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 26
Server version: 10.1.16-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> select version();
+-----------------+
| version()       |
+-----------------+
| 10.1.16-MariaDB |
+-----------------+
1 row in set (0.00 sec)
MariaDB [(none)]> use helei;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [helei]> show create table helei_stu\G\
*************************** 1. row ***************************
       Table: helei_stu
Create Table: CREATE TABLE `helei_stu` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL DEFAULT '',
  `class` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `score` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_class_score` (`class`,`score`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
MariaDB [helei]> explain select * from helei_stu where class=2 and score >60;
+------+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| id   | select_type | table     | type  | possible_keys   | key             | key_len | ref  | rows | Extra                 |
+------+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
|    1 | SIMPLE      | helei_stu | range | idx_class_score | idx_class_score | 2       | NULL |    8 | Using index condition |
+------+-------------+-----------+-------+-----------------+-----------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
MariaDB [helei]> select version();
+-----------------+
| version()       |
+-----------------+
| 10.1.16-MariaDB |
+-----------------+
1 row in set (0.00 sec)

能夠看出,在MariaDB10.1.16中,執行結果以下圖所示:
3d

wKiom1f-5ALQqJT_AAFYyfREDM4523.jpg


——總結——

在MySQL5.5中,無這一特性,因此會先根據class=1來查找記錄,最後根據score>60過濾。而MySQL5.6/MySQL5.7和MariaDB 5.3/5.5/10.0/10.1 版本中,在查找class=1的同時,會根據score>60進行過濾,因此這裏看到的是using index condition。因爲筆者的水平有限,編寫時間也很倉促,文中不免會出現一些錯誤或者不許確的地方,不妥之處懇請讀者批評指正。

相關文章
相關標籤/搜索