当前位置:网站首页>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 )
边栏推荐
- FPGA入门学习(一) - 第一个FPGA工程
- 《多线程下ThreadLocal使用场景实例》
- 种种迹象表明,Apple将有望支持AV1
- 元宇宙日报|元宇宙社交 App“派对岛”产品下架;广州南沙元宇宙产业集聚区揭牌;数字经济发展部际联席会议制度推出
- y9000p2022重装win10问题
- Pytorch深度学习快速入门教程 -- 土堆教程笔记(一)
- There are various signs that apple is expected to support AV1
- SSJ-21B时间继电器
- Fineos announced the open registration of grouptech connect activities in 2022
- System call capture and segmentation - RING3 layer LD_ Preload mechanism for library function hijacking
猜你喜欢
![[ten thousand words long text] Based on LSM tree thought Net 6.0 C # realize kV database (case version)](/img/84/640de0bf779cd45498204909be56d1.png)
[ten thousand words long text] Based on LSM tree thought Net 6.0 C # realize kV database (case version)

Flink 在 讯飞 AI 营销业务的实时数据分析实践

Network protocol: tcp/ip protocol

音视频技术开发周刊 | 255

Hou Peixin, chairman of the openharmony Working Committee of the open atom open source foundation, sent a message to the openatom openharmony sub forum

征婚故事

向日葵远程控制为何采用BGP服务器?自动最优路线、跨运营商高速传输

了解 useRef 一篇就够了

Talking about web vitals

忆凤姐
随机推荐
y9000p2022重装win10问题
什么是OOM,为什么会OOM及一些解决方法
向日葵资深产品总监技术分享:如何在AD域环境下应用
三维点云课程(八)——特征点匹配
元宇宙日报|元宇宙社交 App“派对岛”产品下架;广州南沙元宇宙产业集聚区揭牌;数字经济发展部际联席会议制度推出
Pytest interface automated testing framework | confitest.py
征婚故事
Li Kai: the interesting and cutting-edge audio and video industry has always attracted me
Pytest interface automation test framework | rerun failed cases
Modeling essay series 150 SCLC engineering experiment 3-srule
一些实用、常用、效率越来越高的 Kubernetes 别名
pytest接口自动化测试框架 | pytest常用插件
pytest接口自动化测试框架 | pytest配置文件
浅谈Web Vitals
大量if else判断如何优化?@Valib详解
物联网设备加密的意义
百问百答第48期:极客有约——可观测体系的建设路径
MICCAI2022论文 | 进化多目标架构搜索框架:在COVID-19三维CT分类中的应用
Subject 3 turns and turns
pytest接口自动化测试框架 | pytest的setup和teardown函数