MySQL表關聯join方式
概念引入
- MRR(Multi-Range Read)
處理思路:空間換時間,化隨機讀為順序讀,優化通過二級索引檢索回表的效能問題
MySQL中,索引是B+ tree,在葉子節點中,資料是邏輯有序的,如主鍵索引中,是按照主鍵列有序排列,而二級索引中,是按照索引列進行有序排列,而二級索引的葉子節點儲存的是索引列和主鍵值,索引列是有序的,此時主鍵值卻不一定是有序的,往往是無序的,此時通過索引列定位到主鍵值,然後回表往往是離散的讀取資料。MRR中就是先在記憶體中分配read_rnd_buffer空間,先把二級索引的索引列和主鍵值放入到read_rnd_buffer中(放不下就會分多次放入,清空一批之後放入下一批),然後按照主鍵值排序,這個時候再去回表,IO相對會有序。
注意:MRR需要足夠的資料支撐才行,如果只是少量資料回表,則完全沒必要使用MRR
- Simple Nested-loop Join:只是理論上的一種關聯方式,關聯的表均沒有索引,類似於笛卡兒積,MySQL不會採取這個關聯方式
- Block Nested-loop Join:將驅動表存放到join_buffer中,然後拿著整個join_buffer的資料去與被驅動表進行比較。
BNLJ是對SNLJ的一種優化,BNLJ比較的過程是在記憶體中執行,匹配速度會相對快點,另外個人理解,A和B兩人口袋裡各有一些撲克牌(N個和M個),兩個人撲克牌做匹對。SNLJ就是A從口袋裡一個一個地取出撲克到B的口袋中去匹對,而BNLJ可以理解為取出一把撲克去B的口袋中匹配,可以充分利用CPU的使用情況。但是總體的匹對量是一致均為N*M。
- Index Nested-loop Join:驅動表取出一條資料,然後通過被驅動表的索引進行資料匹配,可以理解為是在SNLJ的基礎上做了一層索引的優化。
- Batched key access:將驅動表放入join_buffer內,並按照索引列進行排序(呼叫了MRR的介面),參考MRR的思路,隨機IO轉順序IO
BKA是對NLJ的一個優化,通過join_buffer和MRR進行優化
這四者的關係大致如下:
如何開啟MRR和BKA
example:MRR
###建立表T
create table t1(id int primary key, a int,create_time timestamp, index(a));
drop procedure idata;
delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=10000)do
insert into t1 values(i, 100001-i, now());
set i=i+1;
end while;
end;;
delimiter ;
call idata();
mysql> explain select * from t1 where a > 100 and a < 500;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | t1 | NULL | range | a | a | 5 | NULL | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
mysql> set optimizer_switch="mrr_cost_based=off";
Query OK, 0 rows affected (0.00 sec)
mysql> explain select * from t1 where a > 100 and a < 500;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+----------------------------------+
| 1 | SIMPLE | t1 | NULL | range | a | a | 5 | NULL | 1 | 100.00 | Using index condition; Using MRR |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+----------------------------------+
1 row in set, 1 warning (0.00 sec)
example:BKA
set optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';
相關文章
- MySQL INNER JOIN關聯多張表的寫法MySql
- 三表關聯查詢-多次LEFT JOIN...ON
- mysql怎麼關聯表?MySql
- mysql-三表關聯MySql
- mysql新建表和多表查詢,關鍵字joinMySql
- mysql 三表關聯查詢MySql
- mysql三表關聯查詢MySql
- Sqlserver update\delete用inner join關聯,會update\delete關鍵字後面的表關聯到的行SQLServerdelete
- mysql三張表關聯查詢MySql
- sql語句左連結left join--3張表關聯SQL
- MYSQL 怎麼 LEFT JOIN 多表聯查MySql
- MySQL join連表查詢示例MySql
- Sql最佳化(二) 關聯(join)SQL
- 表的連線方式:NESTED LOOP、HASH JOIN、SORT MERGE JOIN(轉)OOP
- MYSQL A、B表陣列關聯查詢MySql陣列
- mysql三表關聯查詢練習MySql
- 使用外部表關聯MySQL資料到OracleMySqlOracle
- MySql的join(連線)查詢 (三表 left join 寫法)MySql
- MySQL筆記-左連線的使用(left join有關聯的多表查詢)MySql筆記
- 隨筆:MySQL 普通3表join順序MySql
- MySQL LEFT JOIN/ INNER JOIN/RIGHT JOINMySql
- MySQL 關聯表取最新一條記錄方案MySql
- MySQL三表聯查及兩表聯查MySql
- mysql left join轉inner joinMySql
- 表的關聯關係
- MySQL之表聯結MySql
- mysql + left joinMySql
- MySQL Join BufferMySql
- mysql驅動表、被驅動表、大表小表及join最佳化MySql
- MySQL+關聯(上)MySql
- Mysql join 的本質,Nested Loop Join 和 Hash JoinMySqlOOP
- MySQL JOIN的使用MySql
- MySQL Join語法MySql
- mysql join詳解MySql
- MySQL的Join使用MySql
- 【原】Oracle中Left Outer Join和外關聯(+)的區別Oracle
- Mongodb 關聯表查詢MongoDB
- SQL中聯表查詢操作(LEFT JOIN, RIGHT JOIN, INNER JOIN)SQL