讓order by group by查詢更快

2021-10-06 06:21:15 字數 2208 閱讀 1740

按照排序原理分,mysql排序方式分兩種:

我們可以使用explain來檢視該排序sql的執行計畫,主要看extra欄位:

filesort並不一定是在磁碟檔案中進行排序,也有可能在記憶體中排序,記憶體排序還是磁碟排序取決於排序的資料大小和sort_buffer_size配置的大小:

可以使用trace進行分析,關注number_of_tmp_files欄位,如果等於0,則表示排序過程沒使用臨時檔案,在記憶體中就完成排序;如果大於0,則表示排序過程中使用了臨時檔案。如下圖number_of_tmp_files等於0

,表示未使用臨時檔案進行排序,所以是記憶體排序。

rows:預計掃瞄的行數

examined_row:參與排序的行

number_of_tmp_files:使用臨時檔案的個數

sort_buffers_size:sort_buffer的大小

sort_mode:排序模式

如果number_of_tmp_files等於10,表示使用的是磁碟排序,該sql將需要排序的資料分為7分,然後沒分單獨排序,再存放在7個臨時檔案中,最後把7個臨時檔案合併成乙個大的有序檔案。

filesort下的排序模式總體上由兩種:

mysql通過比較系統變數max_length_for_sort_data 的大小和需要查詢的字段總大小來判斷使用哪種排序模式。

比如:

select a,c,d from t1 where a=

1000

order

by d;

如果是雙路排序的,詳細過程如下:

從索引a找到第乙個滿足a=1000的主鍵id;

然後根據id找出整行,把排序欄位d和主鍵id這兩個字段放到sort_buffer中;

從索引a取出下乙個滿足a=1000記錄的主鍵id;

重複2、3,知道不滿足a=1000;

對sort buffer中的字段d和主鍵id按照欄位d進行排序;

遍歷排序好的id和字段d,按照id的值回到原表中取出a、c、d三個欄位的值返回給客戶端;

如果是單路排序的,詳細過程如下:

從索引a找到第乙個滿足a=1000條件的主鍵id;

根據主鍵id取出整行,取出a、c、d三個欄位的值,放入sort buffer中;

從索引a找到下乙個滿足a=1000的主鍵id;

重複2、3,直到a不滿足條件;

對sort buffer中資料按照欄位d進行排序;

返回結果給客戶端;

對比兩個排序模式,單路排序會把所有需要查詢的字段都放到sort buffer中,而雙路排序只會把主鍵和需要排序的字段放到sort buffer中進行排序,然後再通過主鍵找到原表查詢需要的字段。

如果記憶體足夠的話,可以通過增大max_length_for_sort_data和sort_buffer_size的大小,讓優化器選擇單路排序,把需要的字段都放到sort buffer裡,不用排序後再回原表找到其他字段,直接返回排序結果。

即便排序字段新增了索引,如果返回欄位是所有字段、包含沒有索引的字段、與排序字段不是聯合索引的字段(該字段有索引),也不會走索引。

原因是:掃瞄整個索引並找到沒有索引的字段或者非聯合索引的字段表掃瞄全表的成本更高,所有優化器放棄使用索引。

explain

select id,a,b from t1 where a>

9000

order

by b;

上面的條件查詢是範圍查詢,導致排序結果不走索引。因為a、b兩個欄位是聯合索引,對於單個a的值,b是有序的。而對於a欄位的範圍查詢,也就是a欄位會有多個值,取到a、b的值b就不一定有序了,因此要進行重新排序。

;如上sql,對聯合索引多個字段同時排序,如果乙個是順序,乙個是倒序,則使用不了索引。

預設情況下,會對group by欄位排序,因此優化方式和order by基本一致,如果目的只是分組而不用排序,可以指定order by null禁止排序。

cedega讓我快樂!讓痛苦!

在linux上玩遊戲早不是夢想,很早以前,前輩們都用wine來實現。而複雜的配置讓很對初學者望而卻步。現在,菜鳥也可以輕鬆的在linux上跑起來。cs,極品飛車,魔獸,魔獸世界,一大堆的遊戲都可以在輕易的在linux下跑。它就是cedega,其實它早就有了,只是沒有wine那麼讓人普及,畢竟是要收費...

讓CSS更規範 讓設計居中

摘自 長文字行難以閱讀。隨著現代顯示器的尺寸越來越大,螢幕可讀性問題變得越來越重要。緩解這個問題的一種方法是讓設計居中。居中的設計只佔螢幕的一部分,而不是橫跨螢幕的整個寬度,這樣就會建立比較短的容易閱讀的行。居中的設計目前非常時髦,所以如何在css中設計居中是大多數開發人員首先要學習的主題之一。讓設...

重構,讓人快樂讓人苦

重構,是編寫 必須要面對的一項操作,同時也應該是程式設計師樂於實踐的一項內容。不論是邏輯實現還是設計過程,乃至整個分層結構,我們都可能面臨並且實施重構。這篇文章不會告訴您什麼是重構,如何去優美的重構等等的理論,只想和大家分享一些感受,並且 一些問題。最近的兩周,我一直對我們團隊的乙個子業務框架做重構...