2015-12-22 17:47
874人閱讀收藏
舉報
mysql知識庫
mysq優化(26)
作者同類文章x
mysql在某些情況下可以自動優化表關聯的關聯條件,如:通過分析條件中的字段是否有索引,關聯表中的資料總數之類,通過這些條件mysql便可以實現一些自動優化sql語句的功能。
以下幾種情況基本是靠一些簡單實驗進行驗證,沒有得到確切的官方文件證實
一、inner join情況下mysql自動優化
表結構細節不做介紹,簡單介紹下
bus_creative表中的owner欄位和sys_user表中的id欄位在業務上是外來鍵關聯,n-->1,但是owner欄位沒有建立索引,業務上一般bus_creative資料量大於sys_user,這下就好玩了,先看下通過explain執行後的結果
下面是交換完關聯條件位置後的結果
這裡多說一下explain的id選項
id 列
建表:
create table a(a_id int);
create table b(b_id int);
create table c(c_id int);
mysql> explain select * from a join b on a_id=b_id where b_id in (select c_id from c);
+----+--------------------+-------+...
| id | select_type | table |...
+----+--------------------+-------+...
| 1 | primary | a |...
| 1 | primary | b |...
| 2 | dependent subquery | c |...
+----+--------------------+-------+...
從 3 個表中查詢,對應輸出 3 行,每行對應乙個表, id 列表示執行順序,id 越大,越先執行,id 相同,由上至下執行。此處的執行順序為(以 table 列表示):c -> a -> b
從上面兩個圖中可以看到都是先執行的a表,再執行b表,這是為什麼呢?啪啪的你知道嗎?
來讓哥給你解釋下吧,此時mysql會先分析關聯條件中的兩個欄位owner和id,mysql掐指一算id是主鍵,owner是普通字段沒有索引,這就好辦了,肯定是以有主鍵或者索引的表資料為查詢基準資料,然後遍歷沒有索引欄位的表資料,這樣的結果就是先遍歷a表,然後以a表的資料在b表中進行查詢(因為b中的id是主鍵索引,查的快啊,如果順序反過來你想想會是什麼結果,肯定用不到索引,這樣查詢速度肯定慢!),而且圖2證明交換關聯條件的位置結果也是一樣的,更加印證了上面的邏輯。
乖乖了,原來mysql這麼智慧型啊!
廢個話,要不你個屌絲都能搞個資料庫系統了,還要人家mysql作甚。
接下來看個更屌的
哥哥假想如果把關聯條件中owner也做成索引,此時mysql他老人家該怎麼玩呢,
走起來,哥先建個索引,索引名稱是index_owner,這時我們不妨大膽猜測一下結果,
兩個關鍵點,
1.a表中資料量10萬,b表中資料量2千吧
2.a中owner是索引,b中id是主鍵
此時用你那大腿猜猜都該猜到,肯定是先執行資料量少而且關聯欄位中對方表字段又是索引的那個啊
然後再看看實驗結果吧,上圖
看看吧,mysql他老人家也是這麼想的
二、left/right outer join情況下指定順序執行
基於上面的結果,如果指定了left/right ouert的話,不用想,此時肯定得以left/right指定的那個表為主表先查詢,什麼?要問我為什麼,呵呵,天機不可洩露!我去,你丫滾犢子吧。。。。
因為如果指定了outer後不管怎麼優化指定的表資料肯定是全部顯示,所以肯定先執行了。
有圖有真相就在這裡曬:
換個位置再來一次
頂
0
踩
0
我的同類文章
mysq優化(26)
mysql不同索引的使用情況 檢視索引使用情況
這是以讀為主的線上庫 root read 02 28 07 show status like handler read variable name value handler read first 0 handler read key 0 handler read next 0 handler re...
mysql 檢視索引的使用情況
show status like handler read variable name value handler read first 0 handler read key 0 handler read last 0 handler read next 0 handler read prev 0 ...
mysql三表關聯加索引 mysql 三表索引優化
建表語句 create table if not exists phone phoneid int 10 unsigned not null auto increment,card int 10 unsigned not null,primary key phoneid engine innodb ...