Effective rules for mysql multi-column indexes

Myisam and innodb in mysql use the Btree index by default. It doesn't matter what the data structure of the btree is.
You only need to know the result. Since it is an index, the data structure will be sorted in the end; just like the Xinhua dictionary, his directory is Sorted according to a, b, c.. so
that you can find things faster. For example, if you look for the explanation of the word "中", you will definitely locate the beginning of the z part of the directory; the

combined index can be Understand in this way, for example (a, b, c), abc are all sorted, b under any segment a is sorted, and c under any segment b is sorted;


The effective principle of the combined index is to use it in sequence from front to back. If an index in the middle is not used, the index part before the breakpoint will work, and the index after the breakpoint will not work; for
example

where a = 3  and b = 45  and c = 5 .... There is no breakpoint in the middle of the three index sequences, and they all work;
 where a = 3  and c = 5 ... In this case, b is a break Point, a has an effect, c has no effect,
 where b = 3  and c = 4 ... In this case, a is a breakpoint, and the index after a has no effect. This way of writing the joint index has no effect;
 where b = 45  and a = 3  and c = 5 .... This is the same as the first one, and it all works, as long as abc is used, it has nothing to do with the order of writing

 


(a,b,c) A joint index is added to the three columns (it is a joint index, not a separate index on each column). It should

also be noted that (a,b,c) multi-column index and (a,c,b) ) is different, and looking at the above figure, it can be seen that the relationship order is different;
analyze a few practical examples to strengthen understanding;
analyze the index used in the sentence

copy code
(0)    select * from mytable where a=3 and b=5 and c=4;
The three indexes of abc are all used in the where condition, and they all play a role
(1)    select * from mytable where  c=4 and b=6 and a=3;
This statement is listed only to show that mysql is not so stupid. The order of conditions in where will be automatically optimized by mysql before the query, and the effect is the same as the previous sentence.
(2)    select * from mytable where a=3 and c=7;
a uses the index, b is useless, so c does not use the index effect
(3)    select * from mytable where a=3 and b>7 and c=3;
a is used, b is also used, c is not used, where b is a range value, it is also a breakpoint, but it uses the index itself
(4)    select * from mytable where b=3 and c=4;
Because the a index is not used, the index effect of bc is not used here.
(5)    select * from mytable where a>4 and b=7 and c=9;
a is used b is not used, c is not used
(6)    select * from mytable where a=3 order by b;
a uses the index, and b also uses the effect of the index in the result sorting. As mentioned earlier, the b in any paragraph below a is sorted.
(7)    select * from mytable where a=3 order by c;
a uses the index, but c does not play a sorting effect in this place, because the middle breakpoint, use explain to see filesort
(8)    select * from mytable where b=3 order by a;
b does not use the index, and a does not play the index effect in sorting
copy code

 


Add one:

quickly generate 1000W test database;

Create a test table:

copy code
create table user (  
    id int(10) not null auto_increment,   
    uname  varchar(20) ,  
    regtime   char ( 30 ),  
    age  int(11)   ,
    primary key (id)
)  
engine=myisam default charset=utf8 collate=utf8_general_ci  ,
auto_increment=1 ;
copy code

 

编写存储过程:

copy code
delimiter $$
SET AUTOCOMMIT = 0$$
 
create  procedure test()
begin
declare v_cnt decimal (10)  default 0 ;
dd:loop
          insert  into user values
    (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50),
        (null,rand()*10,now(),rand()*50);
      commit;
        set v_cnt = v_cnt+10 ;
           if  v_cnt = 10000000 then leave dd;
          end if;
         end loop dd ;
end;$$
 
delimiter ;
copy code

 

Call the stored procedure:

call test();

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324463491&siteId=291194637