当前位置:网站首页>Research on MySQL composite index
Research on MySQL composite index
2022-06-24 14:06:00 【minihuabei】
Composite index ( Also known as the union index ), Is an index created on multiple columns . The most important thing to create a composite index is the choice of column order , It's about whether the index can be used , Or how many predicate conditions can be indexed . The use of composite index follows the leftmost matching principle , Only the column to the left of the index matches , The following columns can continue to match . This paper mainly explores the creation order and usage of composite index .
( One ) The concept of composite index
An index created on a single column is called a single column index , stay 2 Indexes created on more than one column are called composite indexes . Creating an index on a single column is relatively easy , Generally, only the selection rate of the column needs to be considered , The more selective , The more scattered the data is , The performance of the index created is better . Usually , The formula for calculating the selection rate of a column is :
selectivity = The number of records returned after the predicate condition is applied / The number of records returned without predicate conditions
The range of optional rate is (0,1], The smaller the value. , The better the selectivity .
For composite indexes ( Also known as the union index ), Is an index created on multiple columns . The most important thing to create a composite index is the choice of column order , It's about whether the index can be used , Or how many predicate conditions can be indexed . The use of composite index follows the leftmost matching principle , Only the column to the left of the index matches , The following columns can continue to match .
( Two ) When will composite index columns be used
Composite indexes follow the leftmost matching principle , Only the leftmost column in the index matches , The next column is likely to be matched . If the left column uses a non equivalent query , The column to the right of the index will not be used by the query , It's not used by sorting .
experiment : In which cases will composite index be used
Which fields in the composite index are used , It's something we're very concerned about . A classic example on the Internet :
-- Create test table
CREATE TABLE t1(
c1 CHAR(1) not null,
c2 CHAR(1) not null,
c3 CHAR(1) not null,
c4 CHAR(1) not null,
c5 CHAR(1) not null
)ENGINE innodb CHARSET UTF8;
-- Add index
alter table t1 add index idx_c1234(c1,c2,c3,c4);
-- Insert test data
insert into t1 values('1','1','1','1','1'),('2','2','2','2','2'),
('3','3','3','3','3'),('4','4','4','4','4'),('5','5','5','5','5');
We need to explore which of the following query statements use the index idx_c1234, And which fields of the index are used ?
(A) where c1=? and c2=? and c4>? and c3=?
(B) where c1=? and c2=? and c4=? order by c3
where c1=? and c4=? group by c3,c2
(D) where c1=? and c5=? order by c2,c3
(E) where c1=? and c2=? and c5=? order by c2,c3
(F) where c1>? and c2=? and c4>? and c3=?
A Options :
mysql> explain select c1,c2,c3,c4,c5 from t1 where c1='2' and c2='2' and c4>'1' and c3='2';
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | t1 | NULL | range | idx_c1234 | idx_c1234 | 12 | NULL | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
The index length used is 12, representative 4 All fields are indexed . because c1、c2、c3 They're all equivalent queries , So the back c4 Columns can also be used .
notes :utf8 code , The length of an index is 3, here 12 representative 4 The index is used for all fields .
B Options :
mysql> explain select c1,c2,c3,c4,c5 from t1 where c1='2' and c2='2' and c4='2' order by c3;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+-----------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 6 | const,const | 1 | 20.00 | Using index condition |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+-----------------------+
The index length used is 6, representative 2 Fields use indexes . According to the leftmost usage principle ,c1、c2 Index is used . Because there is no c3 Predicate conditions , So the index value uses c2 And then there was an interruption , The result is that only c1、c2 Column . here SQL Used order by Sort , But in carrying out the plan Extra Some of them have not filesort keyword , Description in index according to c3 Read the data in order .
Pay special attention to , Although in the index c3 The field is not at the end of the index , But it's used in indexes c2 The ordered nature of fields , Because the execution of the plan Extra Some of them didn't appear "fileasort" keyword . Why is that ? It's used here MySQL5.6 Version introduced Index Condition Pushdown (ICP) Optimize . The core idea is to use the fields in the index to do data filtering . Let's sort it out. Don't use it ICP And use ICP The difference between :
If not used ICP Optimize , Its SQL The execution steps are :
1. Use index columns c1,c2 Get the row data that meets the condition .where c1=‘2’ and c2=‘2’
2. Back to the table to query data , Use where c4='2’ To filter the data
3. Sort the data and output
If used ICP Optimize , Its SQL The execution steps are :
1. Use index columns c1,c2 Get the row data that meets the condition .where c1=‘2’ and c2=‘2’
2. Use... In indexes where c4='2’ To filter the data
3. Because the data is in order , Take out the data that meet the conditions directly in order
C Options :
mysql> explain select c2,c3 from t1 where c1='2' and c4='2' group by c3,c2;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------------------------------------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 3 | const | 2 | 14.29 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------------------------------------------------+
The index length used is 3, representative 1 Fields use indexes . According to the leftmost usage principle ,c1 Index is used . Because there is no c2 Predicate conditions , So the index value uses c1 And then there was an interruption , The result is that only c1 Column . The SQL The execution process is :
1. stay c1 The column uses the index to find c1='2’ All of the line , Then go back to the table and use c4='2’ Filter out mismatched data
2. According to the last step , On the result of c3,c2 Joint sort , In order to get continuously changing data , At the same time, create temporary tables inside the database , Used to store group by Result .
C Option extension :
mysql> explain select c2,c3 from t1 where c1='2' and c4='2' group by c2,c3;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 3 | const | 2 | 14.29 | Using where; Using index |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
The index length used is 3, representative 1 Fields use indexes . According to the leftmost usage principle ,c1 Index is used .
D Options :
mysql> explain select c2,c3 from t1 where c1='2' and c5='2' order by c2,c3;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+------------------------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 3 | const | 2 | 14.29 | Using index condition; Using where |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+------------------------------------+
The index length used is 3, representative 1 All fields are indexed . According to the leftmost usage principle ,c1 Index is used . Because there is no c2 Predicate conditions , So the index value uses c1 And then there was an interruption , The result is that only c1 Column .
D Option extension :
mysql> explain select c2,c3 from t1 where c1='2' and c5='2' order by c3,c2;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+----------------------------------------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 3 | const | 2 | 14.29 | Using index condition; Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+----------------------------------------------------+
The index length used is 3, representative 1 All fields are indexed . According to the leftmost usage principle ,c1 Index is used . Because there is no c2 Predicate conditions , So the index value uses c1 And then there was an interruption , The result is that only c1 Column .
E Options :
mysql> explain select c1,c2,c3,c4,c5 from t1 where c1='2' and c2='2' and c5='2' order by c2,c3;
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+------------------------------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_c1234 | idx_c1234 | 6 | const,const | 2 | 14.29 | Using index condition; Using where |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------------+------+----------+------------------------------------+
The index length used is 6, representative 2 All fields are indexed . According to the leftmost usage principle ,c1、c2 Index is used . here SQL Used order by Sort , But in carrying out the plan Extra Some of them have not filesort keyword , Description in index according to c3 Read the data in order (c2 Is a constant ).
F Options :
mysql> explain select c1,c2,c3,c4,c5 from t1 where c1>'4' and c2='2' and c3='2' and c4='1';
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | t1 | NULL | range | idx_c1234 | idx_c1234 | 3 | NULL | 1 | 20.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------+
The index length used is 3, representative 1 All fields are indexed . According to the leftmost usage principle ,c1 Index is used . here c1 Using the unequal value query , Lead to the following c2 Query cannot use index . This case is very alarming , When predicate condition contains equivalence query and range query , If the range query precedes the index , Then the equivalent query will not be able to use the index ; If the equivalent query comes first , The range query is at the end , The index can be used .
( 3、 ... and ) How to create a composite index
The difficulty of creating composite index lies in the selection of field order , My opinion is as follows :
If there is an equivalent query and sort , When creating a composite index , Put the equivalent query field in the front , Sort at the bottom ;
If there are multiple equivalent queries , Put the selective ones in the front , The less selective ones are put in the back ;
If there is an equivalent query 、 Range queries 、 Sort . The equivalent query comes first , Range query and sorting need to determine the index order according to the actual situation ;
Besides ,《 Alibaba Java Development Manual -2020 The latest Songshan Edition 》 There are several conventions about composite index in , We can have a look :
1. If there is order by Scene , Note the use of index order .order by The fields after are part of the composite index , And at the end of the composite index , Avoid filesort The situation of , Affect query performance .
Example :where a=? b=? order by c; Indexes a_b_c
Counter example : Index if there is range query , Then index ordering will not be used . Such as :where a>10 order by b; Indexes a_b Cannot sort .
2. When building a composite index , The highest discrimination is on the left , If where a=? and b=?,a The value of the column is almost unique , So just create a single column index idx_a that will do .
explain : When there are mixed judgment conditions of equal sign and non equal sign , While indexing , Please precede the equal sign condition . Such as :where c>? and d=?, So even c More differentiated , We must also put d At the top of the index , That is to create an index idx_d_c.
experiment : How to create a composite index
In some documents, we have talked about the creation rules of composite index :ESR principle : accurate (Equal) The matching field comes first , Sort (Sort) Conditions in the middle , Range (Range) The matching field is placed at the end . Now let's explore whether this method is correct .
Example : There are employee tables employees
mysql> show create table employees;
+-----------+-------------------------------
| Table | Create Table
+-----------+-------------------------------------
| employees | CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-----------+-------------------------------------
-- The amount of data is about 30 Line ten thousand
mysql> select count(*) from employees;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
Now we need to check 1998 I'm going to be employed after five years first_name by "Ebbe" staff , And in ascending order by date of birth .
Its SQL The statement is as follows :
select emp_no,birth_date,first_name,last_name,gender,hire_date
from employees
where hire_date >= '1998-01-01'
and first_name = 'Ebbe'
order by birth_date;
To optimize this SQL Statement performance , You need to create an index on the table , In order to ensure where And order by All use indexes , Decided to create a composite index , There is the following order of creation :
(A)hire_date,first_name,birth_date
(B)hire_date,birth_date,first_name
(C)first_name,hire_date,birth_date
(D)first_name,birth_date,hire_date
(E)birth_date,first_name,hire_date
(F)birth_date,hire_date,first_name
Determine which order of index creation is optimal .
Note:
1.date Type account 3 Bytes of space ,hire_date and birth_date All occupied 3 Bytes of space .
2.first_name It's a variable length field , More use 2 Bytes , If allowed NULL value , We need to use more 1 Bytes , Occupy 16 Bytes
A Options :hire_date,first_name,birth_date
create index idx_a on employees(hire_date,first_name,birth_date);
Its implementation plan is as follows :
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | employees | NULL | range | idx_a | idx_a | 19 | NULL | 5678 | 10.00 | Using index condition; Using filesort |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
here key_len The length is 19, It's puzzling ,hire_date Yes no equivalent query , Theoretically key_len Should be 3, By using MySQL workbench View execution plan , It can also be found that the index only uses hire_date Column ( Here's the picture ). Why would it be 19 instead of 3 Well ? It's really puzzling , After thinking for a long time, I haven't figured it out , If you know , I hope you will give me your answers .
B Options :hire_date,birth_date,first_name
To avoid interference , Delete the index created above idx_a, Then create idx_b.
create index idx_b on employees(hire_date,birth_date,first_name);
Its implementation plan is as follows :
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | employees | NULL | range | idx_b | idx_b | 3 | NULL | 5682 | 10.00 | Using index condition; Using filesort |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
here key_len The length is 3,hire_date Yes no equivalent query , The following index columns cannot be used .
C Options :first_name,hire_date,birth_date
To avoid interference , Delete the index created above idx_b, Then create idx_c.
create index idx_c on employees(first_name,hire_date,birth_date);
Its implementation plan is as follows :
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | employees | NULL | range | idx_c | idx_c | 19 | NULL | 5 | 100.00 | Using index condition; Using filesort |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+---------------------------------------+
here key_len The length is 19,first_name It's an equivalent query , Can continue to use hire_date Column , because hire_date Columns are non equivalent queries , The index cannot be used any more birth_date.
D Options :first_name,birth_date,hire_date
To avoid interference , Delete the index created above idx_c, Then create idx_d.
create index idx_d on employees(first_name,birth_date,hire_date);
Its implementation plan is as follows :
+----+-------------+-----------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | employees | NULL | ref | idx_d | idx_d | 16 | const | 190 | 33.33 | Using index condition |
+----+-------------+-----------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
here key_len The length is 16,first_name It's an equivalent query , Not used in predicate filtering birth_date, Lead to only first_name Columns use the upper index , however birth_date Columns are used to sort , The execution plan above shows SQL There's no sort in the end , Explain that the data is from the index according to birth_date It's taken out in order .
E Options :birth_date,first_name,hire_date
To avoid interference , Delete the index created above idx_d, Then create idx_e.
create index idx_e on employees(birth_date,first_name,hire_date);
Its implementation plan is as follows :
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| 1 | SIMPLE | employees | NULL | ALL | NULL | NULL | NULL | NULL | 299468 | 3.33 | Using where; Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
The index is not used here , It shows that sorting column placed at the top of composite index cannot be used .
F Options :birth_date,hire_date,first_name
To avoid interference , Delete the index created above idx_e, Then create idx_f.
create index idx_f on employees(birth_date,hire_date,first_name);
Its implementation plan is as follows :
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| 1 | SIMPLE | employees | NULL | ALL | NULL | NULL | NULL | NULL | 299468 | 3.33 | Using where; Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
And E Options as , The index is not used here , It shows that sorting column placed at the top of composite index cannot be used .
Through the top 6 An index test , We found that , The equivalent query column and the range query column are placed in front of the composite index , Composite indexes can be used to , It's just that the columns used may be different . Which is the best way to create an index ?MySQL Our query optimizer is based on overhead (cost) To choose the best execution plan , Let's take a look at the above 6 The execution cost of each index .
Indexes expenses cost
---------- ------------
idx_a 8518
idx_b 8524
idx_c 13
idx_d 228
idx_e 78083
idx_f 78083
Through the overhead above , You can see :
idx_a and idx_b: The index uses the beginning of the range query field , The index can only be used to the first column , Cannot eliminate sorting , It leads to high cost ;
idx_c and idx_d: The index starts with the equivalent query field , Range queries and sorting come after , The cost is minimal ;
idx_e and idx_f : The index starts with a sort field , The index cannot be used , Full scan of walking , It's expensive .
Further more ,idx_c and idx_d How to choose ?idx_c Using indexes for equivalent queries + Range queries , Then sort the data ;idx_d Using indexes for equivalent queries + Push down query under index condition , Then get the data directly in order . There are advantages and disadvantages in the two ways , Let's take another example :
Top up 6 All indexes are added to the table , Take a look at this SQL Which index will be selected .
mysql> show index from employees;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| employees | 0 | PRIMARY | 1 | emp_no | A | 299468 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_a | 1 | hire_date | A | 5355 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_a | 2 | first_name | A | 290745 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_a | 3 | birth_date | A | 299468 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_b | 1 | hire_date | A | 6237 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_b | 2 | birth_date | A | 297591 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_b | 3 | first_name | A | 299468 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_c | 1 | first_name | A | 1260 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_c | 2 | hire_date | A | 293517 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_c | 3 | birth_date | A | 299468 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_d | 1 | first_name | A | 1218 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_d | 2 | birth_date | A | 294525 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_d | 3 | hire_date | A | 298095 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_e | 1 | birth_date | A | 4767 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_e | 2 | first_name | A | 292761 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_e | 3 | hire_date | A | 299468 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_f | 1 | birth_date | A | 4767 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_f | 2 | hire_date | A | 297864 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_f | 3 | first_name | A | 299468 | NULL | NULL | | BTREE | | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
SQL1
mysql> explain select emp_no,birth_date,first_name,last_name,gender,hire_date
from employees
where hire_date >= '1998-01-01'
and first_name = 'Ebbe'
order by birth_date;
+----+-------------+-----------+------------+-------+-------------------------+-------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+-------------------------+-------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | employees | NULL | range | idx_a,idx_b,idx_c,idx_d | idx_c | 19 | NULL | 5 | 100.00 | Using index condition; Using filesort |
+----+-------------+-----------+------------+-------+-------------------------+-------+---------+------+------+----------+---------------------------------------+
here MySQL Automatically selected idx_c, Because first_name+hire_date Two fields have filtered the data, only 5 That's ok , Because of the lack of data , Sorting is very fast . conversely , If you choose idx_d, You need to pass first_name The fields filter out the qualified 190 Row data , And then use hire_date Filter data , Heavy workload .
SQL2
mysql> explain select emp_no,birth_date,first_name,last_name,gender,hire_date
from employees
where hire_date >= '1980-01-01'
and first_name = 'Ebbe'
order by birth_date;
+----+-------------+-----------+------------+------+-------------------------+-------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+-------------------------+-------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | employees | NULL | ref | idx_a,idx_b,idx_c,idx_d | idx_d | 16 | const | 190 | 50.00 | Using index condition |
+----+-------------+-----------+------------+------+-------------------------+-------+---------+-------+------+----------+-----------------------+
If you choose idx_c,first_name+hire_date After two fields filter data through index , Large amount of data , This leads to very slow sorting .MySQL Automatically selected idx_d, By index first_name Columns filter data , And push and filter through index conditions hire_date Field , And then take the data out of the index in order , relatively speaking , Due to the use idx_d There is no need to sort , It will be faster .
( Four ) Composite index summary
1. The creation of Composite Index , If there are multiple equivalent queries , Put the column with good selectivity at the top , The column with poor selectivity is placed at the back ;
2. The creation of Composite Index , If it involves equivalence query and range query , No matter how selective the columns of non equivalent queries are , The field of equivalent query should be put in front of non equivalent query ;
3. The creation of Composite Index , If it involves equivalence query and range query and sorting (order by、group by), The equivalent query is placed at the top of the index , Which comes first in range query or sort , Which is in the back , It needs to be decided according to the actual situation . If the range query comes first , The order of index cannot be used , Need to be filesort, It is suitable for those with less return results SQL, Because less results leads to less sorting overhead ; If you rank first , You can use the order of the index , But I need to return my watch ( Or under index conditions ) Go look up the data , It is suitable for those who return more results SQL, Because there's no need to sort , Take the data directly .
4. The creation of Composite Index , We must not put order by、group by The column of is placed at the top of the index , Because the query always where Precede order by perform ;
5. Using index for range query will result in subsequent index fields not being used , If there is an order , Can't get rid of filesort Sort . Example :a_b_c Indexes ,where a>? and b = ? order by c, be a Can be used to ,b Can't be used ,c Field needs filesort.
边栏推荐
- [R language data science] (XIV): random variables and basic statistics
- 2022 recurrent training question bank and answers for hoisting signal Rigger (special type of construction work)
- Android kotlin Encyclopedia
- **Puzzling little problem in unity - light and sky box
- 详解kubernetes备份恢复利器 Velero | 深入了解Carina系列第三期
- OpenHarmony 1
- 从谭浩强《C程序设计》上摘录的ASCII码表(常用字符与ASCII代码对照表)
- **Unity中莫名其妙得小问题-灯光和天空盒
- greendao使用问题
- 一键生成大学、专业甚至录取概率,AI填报志愿卡这么神奇?
猜你喜欢

Télétravail: Camping à la maison gadgets de bureau | rédaction communautaire

谷歌WayMo提出R4D: 采用参考目标做远程距离估计

OpenHarmony 1

Dragon lizard developer said: first time you got an electric shock, so you are such a dragon lizard community| Issue 8

万用表的使用方法

Eight major trends in the industrial Internet of things (iiot)

从谭浩强《C程序设计》上摘录的ASCII码表(常用字符与ASCII代码对照表)

【深度学习】NCHW、NHWC和CHWN格式数据的存储形式

puzzle(016.2)指画星河

杰理之TIMER0 用默认的 PA13 来检测脉宽【篇】
随机推荐
puzzle(016.2)指画星河
食品饮料行业渠道商管理系统解决方案:实现渠道数字化营销布局
Jericho turns on shouting in all modes to increase mic automatic mute [chapter]
In the era of knowledge economy, it will teach you to do well in knowledge management
MIT-6.824-lab4A-2022(万字讲解-代码构建)
**Unity中莫名其妙得小问题-灯光和天空盒
2022年江西省安全员B证考试题库模拟考试平台操作
位于相同的分布式端口组但不同主机上的虚拟机无法互相通信
21set classic case
厨卫电器行业B2B交易协同管理平台开发,优化企业库存结构
Kotlin asynchronous flow
Kotlin coroutine context and scheduler
Rasa 3.x 学习系列-非常荣幸成为 Rasa contributors 源码贡献者,和全世界的Rasa源码贡献者共建共享Rasa社区!
【R语言数据科学】(十四):随机变量和基本统计量
遠程辦公之:在家露營辦公小工具| 社區征文
PM也要学会每天反省
Google waymo proposed r4d: remote distance estimation using reference target
如何在物联网低代码平台中进行任务管理?
PM should also learn to reflect every day
Operation of simulated examination platform for examination questions of coal production and operation units (safety production management personnel) in 2022