天天看點

Multi Range Read 代碼路徑

所謂mrr,簡單的說就是當使用二級索引進行檢索并且查詢的列需要回表時,先根據檢索到的pk值進行排序,然後再回表依次查詢聚集索引,進而避免過多的随機io。

測試示例:

建立一個簡單的表:

create table `x1` (

`a` int(11) not null auto_increment,

`b` int(11) default null,

`c` int(11) default null,

primary key (`a`),

key `b` (`b`)

) engine=innodb;

插入大量随機資料:

insert into x1 (b,c) select rand()*100, rand()*10000;

insert into x1 (b,c) select rand()*100, rand()*10000 from x1;

insert into x1 (b,c) select rand()*100, rand()*10000 from x1;

……

執行sql:

root@sb1 04:42:15>set session optimizer_switch=’mrr_cost_based=off';

query ok, 0 rows affected (0.00 sec)root@sb1 04:42:29>explain select * from x1 where b between 60 and 70 limit 10;

+—-+————-+——-+——-+—————+——+———+——+——–+———————————-+

| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | extra                            |

|  1 | simple      | x1    | range | b             | b    | 5       | null | 162690 | using index condition; using mrr |

1 row in set (0.00 sec)

參考代碼:mysql5.6.16

1.優化器階段:

join::optimize

—> make_join_statistics

     —>get_quick_record_count

          —>sql_select::test_quick_select

               —>get_key_scans_params

                    —>check_quick_select

                         —>dsmrr_impl::dsmrr_info_const

                              —>handler::multi_range_read_info_const   //計算mrr的cost

2.初始化:

join::exec —>do_select —> sub_select

—>join_init_read_record

     —>quick_range_select::reset

          —>ha_innobase::multi_range_read_init

               —>dsmrr_impl::dsmrr_init

                    —>dsmrr_impl::dsmrr_fill_buffer

                         multi_range_read_next

                              handler::read_range_first

                              handler::read_range_next

該步驟會讀取請求range的二級索引key範圍,并進行快速排序,主函數dsmrr_impl::dsmrr_fill_buffer

3.讀取聚集索引記錄

join::exec —>do_select—>sub_select—>rr_quick—>

quick_range_select::get_next

     —>ha_innobase::multi_range_read_next

根據之前排好順序的primary key值,依次讀取聚集索引記錄

4.percona的評測:

<a href="http://www.percona.com/blog/2012/03/21/multi-range-read-mrr-in-mysql-5-6-and-mariadb-5-5/">http://www.percona.com/blog/2012/03/21/multi-range-read-mrr-in-mysql-5-6-and-mariadb-5-5/</a>

繼續閱讀