当前位置:网站首页>Detailed explanation of MySQL composite index (multi column index) use and optimization cases
Detailed explanation of MySQL composite index (multi column index) use and optimization cases
2022-07-04 15:16:00 【1024 questions】
1、 Multi column index
2、 Test cases and process
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.4 View execution plan
2.5 Then delete the above index , Add multi column index
2.6 Query again
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 indexWe 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 :
2.5 Then delete the above index , Add multi column indexmysql> select count(*) from payment where staff_id = 2205 AND customer_id = 93112 ;
+----------+
| count(*) |
+----------+
| 178770 |
+----------+
1 row in set (0.12 sec)
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 againmysql> 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 orderThe 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.0005customer_id_selectivity: 0.0500 count(*): 100000001 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 indexesIndexes 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
This is about MySQL Composite index ( Multi column index ) This is the end of the article on use and optimization , More about mysql Please search the previous articles of SDN or continue to browse the relevant articles below. I hope you will support SDN more in the future !
边栏推荐
猜你喜欢
IO流:节点流和处理流详细归纳。
一篇文章搞懂Go语言中的Context
深度学习 网络正则化
I plan to teach myself some programming and want to work as a part-time programmer. I want to ask which programmer has a simple part-time platform list and doesn't investigate the degree of the receiv
Dialogue with ye Yanxiu, senior consultant of Longzhi and atlassian certification expert: where should Chinese users go when atlassian products enter the post server era?
Redis 发布和订阅
近一亿美元失窃,Horizon跨链桥被攻击事件分析
Kubernets pod exists finalizers are always in terminating state
Optimization method of deep learning neural network
LeetCode 1200 最小絕對差[排序] HERODING的LeetCode之路
随机推荐
2022 financial products that can be invested
Leetcode 1200 minimum absolute difference [sort] The Path of leetcode for heroding
LeetCode 1200 最小絕對差[排序] HERODING的LeetCode之路
numpy笔记
【读书会第十三期】FFmpeg 查看媒体信息和处理音视频文件的常用方法
深度学习 网络正则化
Helix swarm Chinese package is released, and perforce further improves the user experience in China
从0到1建设智能灰度数据体系:以vivo游戏中心为例
Ffprobe common commands
Deep learning neural network case (handwritten digit recognition)
Temperature control system based on max31865
Unity脚本API—Time类
The per capita savings of major cities in China have been released. Have you reached the standard?
%S format character
输入宽度!
Is BigDecimal safe to calculate the amount? Look at these five pits~~
Redis 發布和訂閱
Leecode learning notes - Joseph problem
大神详解开源 BUFF 增益攻略丨直播
Unity脚本生命周期 Day02