当前位置:网站首页>Use and optimization of MySQL composite index (multi column index)
Use and optimization of MySQL composite index (multi column index)
2022-07-26 12:03:00 【pan_ junbiao】
Catalog
2.1 Create a test database and data table
2.2 Add two single column indexes
2.3 Query a piece of data using the index of two columns
2.5 Then delete the above index , Add multi column index
3、 Use order of multi column index
3.1 How to choose to build a composite index , Column order
3.2 Rules for using composite indexes
1、 Multi column index
We often hear some people say " hold WHERE The columns in the condition are indexed ", In fact, this suggestion is very wrong .
Building a separate index on multiple columns in most cases does not improve MySQL Query performance of .MySQL stay 5.0 After that, a new technology called “ Index merging ”(index merge) The strategy of , To some extent, multiple single column indexes on the table can be used to locate the specified row . But when the server performs joint operations on multiple indexes , It usually takes a lot of CPU And memory resources in the algorithm cache 、 Sorting and merging operations , Especially when the selectivity of some indexes is not high , When you need to merge and scan a large amount of data . This is the time , We need a multi column index .
2、 Test cases and process
2.1 Create a test database and data table
CREATE DATABASE IF NOT EXISTS db_test default charset utf8 COLLATE utf8_general_ci;
use db_test;
CREATE TABLE payment (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
staff_id INT UNSIGNED NOT NULL,
customer_id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;Use stored procedure to insert 1000w Row random data ( The table engine can be set to MyISAM, Then change it to InnoDB)
DROP PROCEDURE IF EXISTS add_payment;
DELIMITER //
create PROCEDURE add_payment(in num INT)
BEGIN
DECLARE rowid INT DEFAULT 0;
SET @exesql = 'INSERT INTO payment(staff_id, customer_id) values (?, ?)';
WHILE rowid < num DO
SET @staff_id = (1 + FLOOR(5000*RAND()) );
SET @customer_id = (1 + FLOOR(500000*RAND()));
SET rowid = rowid + 1;
prepare stmt FROM @exesql;
EXECUTE stmt USING @staff_id, @customer_id;
END WHILE;
END //
DELIMITER ;2.2 Add two single column indexes
( The execution process takes some time , It is suggested to implement sentence by sentence ):
ALTER TABLE `payment` ADD INDEX idx_customer_id(`customer_id`);
ALTER TABLE `payment` ADD INDEX idx_staff_id(`staff_id`);2.3 Query a piece of data using the index of two columns
select count(*) from payment where staff_id = 2205 AND customer_id = 93112;2.4 View execution plan
mysql> explain select count(*) from payment where staff_id = 2205 AND customer_id = 93112;
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
| 1 | SIMPLE | payment | index_merge | idx_customer_id,idx_staff_id | idx_staff_id,idx_customer_id | 4,4 | NULL | 11711 | Using intersect(idx_staff_id,idx_customer_id); Using where; Using index |
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
1 row in set (0.00 sec)You can see type yes index_merge,Extra Middle tip Using intersect(idx_staff_id,idx_customer_id); This is index merging , Use two indexes , Then merge the two results ( Take intersection or union or both )
Query results :
mysql> select count(*) from payment where staff_id = 2205 AND customer_id = 93112 ;
+----------+
| count(*) |
+----------+
| 178770 |
+----------+
1 row in set (0.12 sec)2.5 Then delete the above index , Add multi column index
ALTER TABLE payment DROP INDEX idx_customer_id;
ALTER TABLE payment DROP INDEX idx_staff_id;
ALTER TABLE `payment` ADD INDEX idx_customer_id_staff_id(`customer_id`, `staff_id`);Be careful , Multi column index pays much attention to the order of index columns ( because customer_id More selective , So put it in front ).
2.6 Query again
mysql> select count(*) from payment where staff_id = 2205 AND customer_id = 93112;
+----------+
| count(*) |
+----------+
| 178770 |
+----------+
1 row in set (0.05 sec)Find queries that are faster with multi column indexes ( The amount of data here is still small , It is more obvious when you are older ).
3、 Use order of multi column index
3.1 How to choose to build a composite index , Column order
The order of columns in a multi column index is critical , There is a rule of thumb about how to choose the column order of an index : Put the most selective column at the forefront of the index ( But not absolutely ). The rule of thumb considers global cardinality and selectivity , Instead of a specific query :
mysql> select count(DISTINCT staff_id) / count(*) AS staff_id_selectivity, count(DISTINCT customer_id) / count(*) AS customer_id_selectivity, count(*) from payment\G;
*************************** 1. row ***************************
staff_id_selectivity: 0.0005
customer_id_selectivity: 0.0500
count(*): 10000000
1 row in set (6.29 sec)customer_id It's more selective , So take it as the first place in the index column .
3.2 Rules for using composite indexes
Indexes can be understood as ordered data structures . Composite index can be understood as , such as (a,b,c),abc It's all in order , In any paragraph a Below b It's all in order , Any paragraph b below c It's all in order ;

The effective rule is : Use from front to back in turn , If an index in the middle is not used , So the index section in front of the breakpoint works , The index after the breakpoint doesn't work ;
such as :
where a=3 and b=45 and c=5 .... This three index sequence uses no breakpoints in the middle , It all works ;
where a=3 and c=5... In this case b It's a breakpoint ,a It worked ,c There is no effect
where b=3 and c=4... In this case a It's a breakpoint , stay a None of the later indexes worked , This method of writing union index has no effect ;
where b=45 and a=3 and c=5 .... This is the same as the first one , It all works ,abc Just use it , It's not about the order of writing (a,b,c) Examples of the use of multi column indexes , explain :(a,b,c) Combine index and (a,c,b) It's different
(0) select * from mytable where a=3 and b=5 and c=4;
abc All three indexes are in where It's used in the conditions , And it all worked
(1) select * from mytable where c=4 and b=6 and a=3;
This statement is listed just to show mysql It's not that stupid ,where The order of the conditions inside will be changed before the query mysql Automatic optimization , The effect is the same as the sentence
(2) select * from mytable where a=3 and c=7;
a Use index ,b of no avail , therefore c There is no index effect
(3) select * from mytable where a=3 and b>7 and c=3;
a Yes ,b Also used. ,c Not used , This place b It's the range value , It's also a breakpoint , It just uses the index itself
(4) select * from mytable where b=3 and c=4;
because a The index is not used , So here bc No indexing effect
(5) select * from mytable where a>4 and b=7 and c=9;
a Yes b Not used ,c Not used
(6) select * from mytable where a=3 order by b;
a Index is used ,b Index effect is also used in result sorting , I said before. ,a In any of the following paragraphs b It's in order
(7) select * from mytable where a=3 order by c;
a Index is used , But this place c No ranking effect , Because there's a break in the middle , Use explain You can see filesort
(8) select * from mytable where b=3 order by a;
b No index is used , Sorting a It doesn't have an indexing effect Original author : Qin Tian
Original address :https://blog.csdn.net/demored/article/details/123068511
( Thanks to the original author for sharing )
边栏推荐
- Pytorch深度学习快速入门教程 -- 土堆教程笔记(一)
- pytest接口自动化测试框架 | 重新运行失败用例
- Is it easy to find a job after programmer training?
- Modeling essay series 151 SCLC engineering experiment 4-sclc object
- 三维点云课程(八)——特征点匹配
- DS-24C/DC220V时间继电器
- 面试官:如何理解QPS,TPS,RT?
- flink 写redis 比较慢,大家有啥思路优化吗?
- Win10 uses NVM to install node, NPM, and cnpm
- 3.1 create menu and game page - up
猜你喜欢
随机推荐
Understanding useref is enough
Ga-rpn: recommended area network for guiding anchors
pytest接口自动化测试框架 | pytest配置文件
Who is responsible for the problems of virtual idol endorsement products? And listen to the lawyer's analysis
种种迹象表明,Apple将有望支持AV1
Flutter 学习之路
Recalling Sister Feng
请问下有人知道FlinkSQL 的 Retrack 在哪里可以指定吗? 网上资料只看到API 代码设
pytest接口自动化测试框架 | 通过标记表达式执行用例
了解 useRef 一篇就够了
GA-RPN:引导锚点的建议区域网络
DS-112时间继电器
MATLAB中strjoin函数使用
There are various signs that apple is expected to support AV1
System call capture and analysis - ring layer kprobe hijacks system calls
Pytest interface automated testing framework | introduction to fixture of pytest
Pytoch deep learning quick start tutorial -- mound tutorial notes (II)
Flutter JNI confusion introduction.So file release package flash back
剑指 Offer 24. 反转链表
11 "pocket" universities in China! Running on campus and leaving the school before accelerating









