日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql join大小表顺讯_MySQL优化器join顺序

發(fā)布時間:2025/4/5 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql join大小表顺讯_MySQL优化器join顺序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前一篇介紹了cost的計算方法,下面測試一下兩表關聯(lián)的查詢:

測試用例

CREATE TABLE `xpchild` (

`id` int(11) NOT NULL,

`name` varchar(100) DEFAULT NULL,

`c1` int(11) DEFAULT NULL,

`c2` int(11) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `xpchild_name` (`name`),

KEY `xpchild_id_c1` (`id`,`c1`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `xpchild_1` (

`xxid` bigint(20) DEFAULT NULL,

`name` varchar(100) DEFAULT NULL,

KEY `xpchild_1_id` (`xxid`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

測試sql

select * from xpchild, xpchild_1 where xpchild.id=100 and xpchild.id=xpchild_1.xxid;

函數(shù)調(diào)用棧:

JOIN::optimize

make_join_statistics

update_ref_and_keys

get_quick_record_count

choose_plan

以上省略了JOIN::prepare的過程,prepare主要進行一些等級變化,上面的sql是一個比較簡單的兩表關聯(lián),并不會進行過多的變換。

step1: 初始化

make_join_statistics:

根據(jù)select_lex->leaf_tables初始化每個JOIN_TAB對象,至此,一個sql對于一個join,對應兩個join_tab.

初始化quick_condition_rows為innodb中的stat統(tǒng)計信息中的record記錄數(shù)。

step 2: 查詢可用索引

update_ref_and_keys:根據(jù)where條件,選擇可以使用的索引,加入到possible keys中,本例子加入的keys包括:

xpchild: primary,xpchild_id_c1

xpchild_1: xxid

(gdb) p *keyuse_array

$67 = {

buffer = 0x8ca1fb58 "@24214",

elements = 3,

max_element = 20,

alloc_increment = 64,

size_of_element = 48

step 3: 計算cost

get_quick_record_count:根據(jù)可選擇的possible_keys計算cost。

1. xpchild表

因為有可以使用的primary,xpchild表s->type == JT_CONST,所以cost的計算為:

s->found_records=s->records=s->read_time=1。

所以,mysql對于使用primary,unique key的使用上比較有傾向性,而且可以節(jié)省大量的計算cost的時間。

2. xpchild_1表:

全表掃描的records && read_time是:

s->found_records= 1215

s->read_time= 5

計算xxid索引的cost:

get_quick_record_count

test_quick_select:

最終計算的cost:

estimated_records=1

best_read_time=2.21

具體的計算方式,可以參考前面一篇博客

到此:xpchild的JOIN_TAB結構中,比較簡單,const table類型,cost=1;

xpchild_1的JOIN_TAB結構中,found_records=1, read_time=2.21;

對于單表的的查詢access path已經(jīng)是最優(yōu)的。

step 4:join的順序:

choose_join:

1. 如果是const table;不再進行join順序的計算,直接選擇使用當前positions。

memcpy((uchar*) join->best_positions,(uchar*) join->positions,sizeof(POSITION)*join->const_tables);

join->best_read=1.0;

2. 為非const table,選擇最優(yōu)的訪問順序

optimizer_search_depth:優(yōu)化訪問表join順序的遞歸計算深度。

straight_join:按照sql的順序,或者添加sql hint確定的順序,默認不使用

greedy_search:貪婪算法,對于當前的查詢,在候選的表中,選擇一個最小cost添加到當前的plan中,遞歸完成。

best_extension_by_limited_search:根據(jù)current_record_count,與調(diào)用best_access_path得到的best_record_count進行比較,選擇最優(yōu)的路徑。

best_access_path:table->quick_rows根據(jù)前面計算的records,得出cost,得到join->positions[idx]的最優(yōu)路徑。

join順序選擇的步驟:

1. 根據(jù)best_extension_by_limited_search在remaining table中選擇cost最小的那個,本例中,xpchild的cost為:records=1 , read_time=0。所以選擇為第一張表。

2. 然后從候選表中選擇一個(只剩下xpchild_1表)加入到join的順序中,并根據(jù)best_access_path選擇一個cost最低的執(zhí)行計劃加入到plan中,這里選擇xpchild_1_id的索引。

最后得到best plan,并賦值給last_query_cost;

join->thd->status_var.last_query_cost= join->best_read;

最后得到的best plan:

(gdb) p tab->join->best_read

$73 = 1.1990000000000001

(gdb) p tab->join->best_positions

$72 = {{

records_read = 1,

read_time = 0,

table = 0x8ca06078, 'xpchild'

key = 0x8ca1fb58, 'primary'

ref_depend_map = 0

}, {

records_read = 1,

read_time = 1,

table = 0x8ca0620c, 'xpchild_1'

key = 0x8ca1fbb8, 'xpchild_1_id'

ref_depend_map = 0

}

未完待續(xù):

總結

以上是生活随笔為你收集整理的mysql join大小表顺讯_MySQL优化器join顺序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。