主仆调教SM束缚绳索捆绑,成品人和精品人的区别三叶草,双性受被各种性器调教学生小说,精品一区二区三区水蜜桃

MySQL高級 第11章排序分組優化

where 條件和 on的判斷這些過濾條件,作為優先優化的部門,是要被先考慮的!其次,如果有分組和排序,那么也要考慮grouo by 和order by。

1. 無過濾不索引

create index idx_age_deptid_name on emp (age,deptid,name);

explain select * from emp where age=40 order by deptid;

explain ?select * from emp order by age,deptid;

explain ?select * from emp order by age,deptid limit 10;

4. 索引的選擇

①首先,清除emp上面的所有索引,只保留主鍵索引!

drop index idx_age_deptid_name on emp;

②查詢:年齡為30歲的,且員工編號小于101000的用戶,按用戶名稱排序

explain SELECT SQL_NO_CACHE * FROM emp WHERE age =30 AND empno <101000 ORDER BY NAME ;

③全表掃描肯定是不被允許的,因此我們要考慮優化。

思路:首先需要讓where的過濾條件,用上索引;

查詢中,age.empno是查詢的過濾條件,而name則是排序的字段,因此我們來創建一個此三個字段的復合索引:

create index idx_age_empno_name on emp(age,empno,name);

再次查詢,發現using filesort依然存在。

原因: empno是范圍查詢,因此導致了索引失效,所以name字段無法使用索引排序。

所以,三個字段的符合索引,沒有意義,因為empno和name字段只能選擇其一!

 

④解決: 魚與熊掌不可兼得,因此,要么選擇empno,要么選擇name

drop index idx_age_empno_name on emp;

create index idx_age_name on emp(age,name);

create index idx_age_empno on emp(age,empno);

兩個索引同時存在,mysql會選擇哪個?

原因:所有的排序都是在條件過濾之后才執行的,所以如果條件過濾了大部分數據的話,幾百幾千條數據進行排序其實并不是很消耗性能,即使索引優化了排序但實際提升性能很有限。 ?相對的 empno<101000 這個條件如果沒有用到索引的話,要對幾萬條的數據進行掃描,這是非常消耗性能的,使用empno字段的范圍查詢,過濾性更好(empno從100000開始)!

 

結論: 當范圍條件和group by 或者 order by ?的字段出現二選一時 ,優先觀察條件字段的過濾數量,如果過濾的數據足夠多,而需要排序的數據并不多時,優先把索引放在范圍字段上。反之,亦然。

5. using filesort?

5.1 mysql的排序算法

①雙路排序

MySQL 4.1之前是使用雙路排序,字面意思就是兩次掃描磁盤,最終得到數據,讀取行指針和orderby列,對他們進行排序,然后掃描已經排序好的列表,按照列表中的值重新從列表中讀取對應的數據輸出。

從磁盤取排序字段,在buffer進行排序,再從磁盤取其他字段。

簡單來說,取一批數據,要對磁盤進行了兩次掃描,眾所周知,I\O是很耗時的,所以在mysql4.1之后,出現了第二種改進的算法,就是單路排序。

②單路排序

從磁盤讀取查詢需要的所有列,按照order by列在buffer對它們進行排序,然后掃描排序后的列表進行輸出,

它的效率更快一些,避免了第二次讀取數據。并且把隨機IO變成了順序IO,但是它會使用更多的空間,

因為它把每一行都保存在內存中了。

③單路排序的問題

由于單路是后出的,總體而言好過雙路。但是存在以下問題:

在sort_buffer中,方法B比方法A要多占用很多空間,因為方法B是把所有字段都取出, 所以有可能取出的數據的總大小超出了sort_buffer的容量,導致每次只能取sort_buffer容量大小的數據,進行排序(創建tmp文件,多路合并),排完再取取sort_buffer容量大小,再排……從而多次I/O。

???結論:本來想省一次I/O操作,反而導致了大量的I/O操作,反而得不償失。

5.2 如何優化

①增大sort_butter_size參數的設置

不管用哪種算法,提高這個參數都會提高效率,當然,要根據系統的能力去提高,因為這個參數是針對每個進程的??1M-8M之間調整。

②增大max_length_for_sort_data參數的設置

mysql使用單路排序的前提是排序的字段大小要小于max_length_for_sort_data。

提高這個參數,會增加用改進算法的概率。但是如果設的太高,數據總容量超出sort_buffer_size的概率就增大,明顯癥狀是高的磁盤I/O活動和低的處理器使用率。(1024-8192之間調整)。

③減少select 后面的查詢的字段。

當Query的字段大小總和小于max_length_for_sort_data 而且排序字段不是?TEXT|BLOB 類型時,會用改進后的算法——單路排序,?否則用老算法——多路排序。

兩種算法的數據都有可能超出sort_buffer的容量,超出之后,會創建tmp文件進行合并排序,導致多次I/O,但是用單路排序算法的風險會更大一些,所以要提高sort_buffer_size。

6. 使用覆蓋索引

覆蓋索引:SQL只需要通過索引就可以返回查詢所需要的數據,而不必通過二級索引查到主鍵之后再去查詢數據。

7. group by

group by 使用索引的原則幾乎跟order by一致 ,唯一區別是groupby 即使沒有過濾條件用到索引,也可以直接使用索引。

 

  1. 主站蜘蛛池模板: 民勤县| 平顶山市| 广西| 广河县| 西宁市| 林甸县| 治多县| 突泉县| 海兴县| 大庆市| 晋江市| 扬中市| 嵩明县| 枣阳市| 岳池县| 南开区| 远安县| 南开区| 诸暨市| 八宿县| 松原市| 鹤壁市| 安塞县| 托克托县| 乌拉特中旗| 房山区| 海淀区| 北辰区| 于都县| 西乌珠穆沁旗| 宁陵县| 八宿县| 玉田县| 伊金霍洛旗| 阿荣旗| 满城县| 永靖县| 团风县| 璧山县| 措美县| 清丰县|