MySQL何時會使用內部臨時表?

1.union執行過程mysql

首先咱們建立一個表t1算法

create table t1(id int primary key, a int, b int, index(a));
delimiter ;;
create procedure idata()
begin
  declare i int;
  set i=1;
  while(i<=1000)do
    insert into t1 values(i, i, i);
    set i=i+1;
  end while;
end;;
delimiter ;
call idata();

而後咱們執行一下這條語句sql

explain select 1000 as f union (select id from t1 order by id desc limit 2)

首先說下union的語義,union的語義是取兩個結果的並集,重複的保留一行,而後咱們來看下explain的結果,第二行的key=PRIMARY,說明用到了主鍵索引。mysql優化

第三行的Extra的Using temporary說明用到了臨時表優化

 

下面咱們看下這條語句的執行流程:spa

1.建立一個臨時表,只有f一個字段,且爲主鍵code

2.將1000這個數據插入臨時表blog

3.子查詢中步驟:排序

1.插入1000進入臨時表,由於主鍵衝突,插入失敗索引

2.插入第二行900,插入成功

4.將臨時表數據做爲結果返回,並刪除臨時表

這個過程的流程圖以下:

若是咱們把union改爲union all,就不須要使用臨時表了,由於union all是重複的也保留,

你們能夠看到extra這一列已經沒有了Using temporary

explain select 1000 as f union all (select id from t1 order by id desc limit 2)

2.group by執行過程

咱們來看下面這條語句:

explain select id%10 as m, count(*) as c from t1 group by m;

能夠看到explain結果

Using index(使用到了覆蓋索引a,不須要回表); Using temporary(用到了臨時表); Using filesort(對數據進行了排序)

這條語句的意思是將id%10進行分組統計,並按照m進行排序

執行流程以下:

1.建立臨時表,增長m,c字段,m是主鍵

2.計算id%10的結果記爲x

3.若是臨時表裏面沒有主鍵爲x的行,則插入(x,1),若是有的話,就將該行的c值加1

4.遍歷完成後,按照m字段排序返回結果給客戶端

流程圖以下

接下來咱們看下這條語句的執行結果

explain select id%10 as m, count(*) as c from t1 group by m

其實,若是咱們不須要對查詢結果進行排序,咱們能夠加一個order by null

咱們執行一下這條語句

explain select id%10 as m, count(*) as c from t1 group by m order by null

能夠看到這裏沒有進行排序,因爲掃描是從表t的id是從1開始的,因此第一行是1

若是咱們執行下列語句,會發生什麼呢?

咱們上面說的臨時表,實際上是內存臨時表,若是咱們把內存臨時表的容量改的比咱們要查詢的數據的容量小,那麼就會使用到磁盤臨時表,磁盤臨時表的默認引擎是innodb

et tmp_table_size=1024;
select id%100 as m, count(*) as c from t1 group by m order by null limit 10

  

group by 優化方法--直接排序

其實在上面的關於從內存臨時錶轉化成磁盤臨時表是很浪費時間的,也就是說mysql,在執行過程當中發現空間不夠了,在轉成磁盤臨時表,可是若是咱們直接告訴mysql,我要查詢的數據很大,那麼mysql優化器就會想到,既然你告訴我數據很大,那麼我就直接用sort_buffer進行排序,若是sort_buffer內存不夠大,會用到磁盤臨時表輔助排序。

select SQL_BIG_RESULT id%100 as m, count(*) as c from t1 group by m;

小結一下:

1.若是咱們不須要對統計結果進行排序,能夠加上order by null省去排序流程。

2.儘可能讓排序過程用上內存臨時表,能夠經過適當調大tmp_table_size的值來避免用到磁盤臨時表。

3.若是數據量實在太大,使用SQL_BIG_RESULT告訴優化器,直接使用排序算法。

相關文章
相關標籤/搜索