1. 程式人生 > >distinct、order by、 group by實現原理

distinct、order by、 group by實現原理

前言

除了常規的Join語句之外,還有一類Query語句也是使用比較頻繁的,那就是ORDERBY,GROUP BY以及DISTINCT這三類查詢。考慮到這三類查詢都涉及到資料的排序等操作,所以我將他們放在了一起,下面就針對這三類Query語句做基本的分析。

ORDER BY 的實現與優化

在MySQL中,ORDERBY的實現有如下兩種型別:

一種是通過有序索引而直接取得有序的資料,這樣不用進行任何排序操作即可得到滿足客戶端要求的有序資料返回給客戶端;

另外一種則需要通過MySQL的排序演算法將儲存引擎中返回的資料進行排序然後再將排序後的資料返回給客戶端。

下面我們就針對這兩種實現方式做一個簡單的分析。首先分析一下第一種不用排序的實現方式。同樣還是通過示例來說話吧:

複製程式碼
[email protected] : example 09:48:41> EXPLAIN
-> SELECT m.id,m.subject,c.content
-> FROM group_message m,group_message_content c
-> WHERE m.group_id = 1 AND m.id = c.group_msg_id
-> ORDER BY m.user_id\G

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: m
type: ref
possible_keys: PRIMARY,idx_group_message_gid_uid
key: idx_group_message_gid_uid
key_len: 
4 ref: const rows: 4 Extra: Using where *************************** 2. row *************************** id: 1 select_type: SIMPLE table: c type: ref possible_keys: group_message_content_msg_id key: group_message_content_msg_id key_len: 4 ref: example.m.id rows: 11 Extra:
複製程式碼

看看上面的這個Query語句,明明有ORDER BY user_id,為什麼在執行計劃中卻沒有排序操作呢?其實這裡正是因為MySQL Query Optimizer選擇了一個有序的索引來進行訪問表中的資料(idx_group_message_gid_uid),這樣,我們通過group_id的條件得到的資料已經是按照group_id和user_id進行排序的了。而雖然我們的排序條件僅僅只有一個user_id,但是我們的WHERE條件決定了返回資料的group_id全部一樣,也就是說不管有沒有根據group_id來進行排序,返回的結果集都是完全一樣的。

我們可以通過如下的圖示來描述整個執行過程:

 clip_image002

圖中的TableA和TableB分別為上面Query中的group_message和gruop_message_content這兩個表。

這種利用索引實現資料排序的方法是MySQL中實現結果集排序的最佳做法,可以完全避免因為排序計算所帶來的資源消耗。所以,在我們優化Query語句中的ORDERBY的時候,儘可能利用已有的索引來避免實際的排序計算,可以很大幅度的提升ORDERBY操作的效能。在有些Query的優化過程中,即使為了避免實際的排序操作而調整索引欄位的順序,甚至是增加索引欄位也是值得的。當然,在調整索引之前,同時還需要評估調整該索引對其他Query所帶來的影響,平衡整體得失。

如果沒有索引利用的時候,MySQL又如何來實現排序呢?這時候MySQL無法避免需要通過相關的排序演算法來將儲存引擎返回的資料進行排序運算了。下面我們再針對這種實現方式進行相應的分析。

在MySQL第二種排序實現方式中,必須進行相應的排序演算法來實現資料的排序。MySQL目前可以通過兩種演算法來實現資料的排序操作。

取出滿足過濾條件的用於排序條件的欄位以及可以直接定位到行資料的行指標資訊,在Sort Buffer中進行實際的排序操作,然後利用排好序之後的資料根據行指標資訊返回表中取得客戶端請求的其他欄位的資料,再返回給客戶端;

根據過濾條件一次取出排序欄位以及客戶端請求的所有其他欄位的資料,並將不需要排序的欄位存放在一塊記憶體區域中,然後在SortBuffer中將排序欄位和行指標資訊進行排序,最後再利用排序後的行指標與存放在記憶體區域中和其他欄位一起的行指標資訊進行匹配合並結果集,再按照順序返回給客戶端。

上面第一種排序演算法是MySQL一直以來就有的排序演算法,而第二種則是從MySQL4.1版本才開始增加的改進版排序演算法。第二種演算法與第一種相比較,主要優勢就是減少了資料的二次訪問。在排序之後不需要再一次回到表中取資料,節省了IO操作。當然,第二種演算法會消耗更多的記憶體,正是一種典型的通過記憶體空間換取時間的優化方式。下面我們同樣通過一個例項來看看當MySQL不得不使用排序演算法的時候的執行計劃,僅僅只是更改一下排序欄位:

複製程式碼
[email protected] : example 10:09:06> explain
-> select m.id,m.subject,c.content
-> FROM group_message m,group_message_content c
-> WHERE m.group_id = 1 AND m.id = c.group_msg_id
-> ORDER BY m.subject\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: m
type: ref
possible_keys: PRIMARY,idx_group_message_gid_uid
key: idx_group_message_gid_uid
key_len: 4
ref: const
rows: 4
Extra: Using where; Using filesort

*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: ref
possible_keys: group_message_content_msg_id
key: group_message_content_msg_id
key_len: 4
ref: example.m.id
rows: 11
Extra:
複製程式碼

大概一看,好像整個執行計劃並沒有什麼區別啊?但是細心的讀者朋友可能已經發現,在group_message表的Extra資訊中,多了一個“Using filesort”的資訊,實際上這就是MySQL Query Optimizer在告訴我們,他需要進行排序操作才能按照客戶端的要求返回有序的資料。執行圖示如下:

clip_image002[5] 

這裡我們看到了,MySQL在取得第一個表的資料之後,先根據排序條件將資料進行了一次filesort,也就是排序操作。然後再利用排序後的結果集作為驅動結果集來通過Nested Loop Join訪問第二個表。當然,大家不要誤解,這個filesort並不是說通過磁碟檔案進行排序,僅僅只是告訴我們進行了一個排序操作。

上面,我們看到了排序結果集來源僅僅只是單個表的比較簡單的filesort操作。而在我們實際應用中,很多時候我們的業務要求可能並不是這樣,可能需要排序的欄位同時存在於兩個表中,或者MySQL在經過一次Join之後才進行排序操作。這樣的排序在MySQL中並不能簡單的裡利用Sort Buffer進行排序,而是必須先通過一個臨時表將之前Join的結果集存放入臨時表之後在將臨時表的資料取到Sort Buffer中進行操作。下面我們通過再次更改排序要求來示例這樣的執行計劃,當我們選擇通過group_message_content表上面的content欄位來進行排序之後:

複製程式碼
[email protected] : example 10:22:42> explain
-> select m.id,m.subject,c.content
-> FROM group_message m,group_message_content c
-> WHERE m.group_id = 1 AND m.id = c.group_msg_id
-> ORDER BY c.content\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: m
type: ref
possible_keys: PRIMARY,idx_group_message_gid_uid
key: idx_group_message_gid_uid
key_len: 4
ref: const
rows: 4
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: ref
possible_keys: group_message_content_msg_id
key: group_message_content_msg_id
key_len: 4
ref: example.m.id
rows: 11
Extra:
複製程式碼

這時候的執行計劃中出現了“Using temporary”,正是因為我們的排序操作需要在兩個表Join之後才能進行,下圖展示了這個Query的執行過程:

 clip_image002[7]

首先是TableA和TableB進行Join,然後結果集進入臨時表,再進行filesort,最後得到有序的結果集資料返回給客戶端。

上面我們通過兩個不同的示例展示了當MySQL無法避免要使用相應的排序演算法進行排序操作的時候的實現原理。雖然在排序過程中所使用的排序演算法有兩種,但是兩種排序的內部實現機制大體上差不多。

當我們無法避免排序操作的時候,我們又該如何來優化呢?很顯然,我們應該儘可能讓MySQL選擇使用第二種演算法來進行排序。這樣可以減少大量的隨機IO操作,很大幅度的提高排序工作的效率。

1.加大max_length_for_sort_data引數的設定;

在MySQL中,決定使用第一種老式的排序演算法還是新的改進演算法的依據是通過引數max_length_for_sort_data來決定的。當我們所有返回欄位的最大長度小於這個引數值的時候,MySQL就會選擇改進後的排序演算法,反之,則選擇老式的演算法。所以,如果我們有充足的記憶體讓MySQL存放需要返回的非排序欄位的時候,可以加大這個引數的值來讓MySQL選擇使用改進版的排序演算法。

2. 去掉不必要的返回欄位;

當我們的記憶體並不是很充裕的時候,我們不能簡單的通過強行加大上面的引數來強迫MySQL去使用改進版的排序演算法,因為如果那樣可能會造成MySQL不得不將資料分成很多段然後進行排使用序,這樣的結果可能會得不償失。在這種情況下,我們就需要去掉不必要的返回欄位,讓我們的返回結果長度適應max_length_for_sort_data引數的限制。

3.增大sort_buffer_size引數設定;

增大sort_buffer_size並不是為了讓MySQL可以選擇改進版的排序演算法,而是為了讓MySQL可以儘量減少在排序過程中對需要排序的資料進行分段,因為這樣會造成MySQL不得不使用臨時表來進行交換排序。

GROUP BY 的實現與優化

由於GROUP BY實際上也同樣需要進行排序操作,而且與ORDER BY相比,GROUP BY主要只是多了排序之後的分組操作。當然,如果在分組的時候還使用了其他的一些聚合函式,那麼還需要一些聚合函式的計算。所以,在GROUP BY的實現過程中,與ORDERBY一樣也可以利用到索引。

在MySQL中,GROUP BY的實現同樣有多種(三種)方式,其中有兩種方式會利用現有的索引資訊來完成GROUP BY,另外一種為完全無法使用索引的場景下使用。下面我們分別針對這三種實現方式做一個分析。

1. 使用鬆散(Loose)索引掃描實現GROUP BY

何謂鬆散索引掃描實現GROUP BY呢?實際上就是當MySQL完全利用索引掃描來實現GROUP BY的時候,並不需要掃描所有滿足條件的索引鍵即可完成操作得出結果。

下面我們通過一個示例來描述鬆散索引掃描實現GROUP BY,在示例之前我們需要首先調整一下group_message表的索引,將gmt_create欄位新增到group_id和user_id欄位的索引中:

複製程式碼
[email protected] : example 08:49:45> create index idx_gid_uid_gc
-> on group_message(group_id,user_id,gmt_create);
Query OK, rows affected (0.03 sec)
Records: 96 Duplicates: 0 Warnings: 0
[email protected] : example 09:07:30> drop index idx_group_message_gid_uid
-> on group_message;
Query OK, 96 rows affected (0.02 sec)
Records: 96 Duplicates: 0 Warnings: 0
複製程式碼

然後再看如下Query的執行計劃:

複製程式碼
[email protected] : example 09:26:15> EXPLAIN
-> SELECT user_id,max(gmt_create)
-> FROM group_message
-> WHERE group_id < 10
-> GROUP BY group_id,user_id\G

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: range
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 8
ref: NULL
rows: 4
Extra: Using where; Using index for group-by
1 row in set (0.00 sec)
複製程式碼

我們看到在執行計劃的Extra資訊中有資訊顯示“Using index for group-by”,實際上這就是告訴我們,MySQLQueryOptimizer通過使用鬆散索引掃描來實現了我們所需要的GROUP BY操作。

下面這張圖片描繪了掃描過程的大概實現:要利用到鬆散索引掃描實現GROUP BY,需要至少滿足以下幾個條件:

clip_image002[9]

GROUP BY 條件欄位必須在同一個索引中最前面的連續位置;

在使用GROUP BY的同時,只能使用MAX和MIN這兩個聚合函式;

如果引用到了該索引中GROUP BY條件之外的欄位條件的時候,必須以常量形式存在;

為什麼鬆散索引掃描的效率會很高?

因為在沒有WHERE子句,也就是必須經過全索引掃描的時候,鬆散索引掃描需要讀取的鍵值數量與分組的組數量一樣多,也就是說比實際存在的鍵值數目要少很多。而在WHERE子句包含範圍判斷式或者等值表示式的時候,鬆散索引掃描查詢滿足範圍條件的每個組的第1個關鍵字,並且再次讀取儘可能最少數量的關鍵字。

2. 使用緊湊(Tight)索引掃描實現GROUP BY

緊湊索引掃描實現GROUP BY和鬆散索引掃描的區別主要在於他需要在掃描索引的時候,讀取所有滿足條件的索引鍵,然後再根據讀取惡的資料來完成GROUP BY操作得到相應結果。

複製程式碼
[email protected] : example 08:55:14> EXPLAIN
-> SELECT max(gmt_create)
-> FROM group_message
-> WHERE group_id = 2
-> GROUP BY user_id\G

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message

type: ref
possible_keys: idx_group_message_gid_uid,idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: const
rows: 4
Extra: Using where; Using index
1 row in set (0.01 sec)
複製程式碼

這時候的執行計劃的Extra資訊中已經沒有“Using index for group-by”了,但並不是說MySQL的GROUP BY操作並不是通過索引完成的,只不過是需要訪問WHERE條件所限定的所有索引鍵資訊之後才能得出結果。這就是通過緊湊索引掃描來實現GROUP BY的執行計劃輸出資訊。

下面這張圖片展示了大概的整個執行過程:

clip_image002[11] 

在MySQL中,MySQL Query Optimizer首先會選擇嘗試通過鬆散索引掃描來實現GROUP BY操作,當發現某些情況無法滿足鬆散索引掃描實現GROUP BY的要求之後,才會嘗試通過緊湊索引掃描來實現。

當GROUP BY條件欄位並不連續或者不是索引字首部分的時候,MySQL Query Optimizer無法使用鬆散索引掃描,設定無法直接通過索引完成GROUP BY操作,因為缺失的索引鍵資訊無法得到。但是,如果Query語句中存在一個常量值來引用缺失的索引鍵,則可以使用緊湊索引掃描完成GROUP BY操作,因為常量填充了搜尋關鍵字中的“差距”,可以形成完整的索引字首。這些索引字首可以用於索引查詢。而如果需要排序GROUP BY結果,並且能夠形成索引字首的搜尋關鍵字,MySQL還可以避免額外的排序操作,因為使用有順序的索引的字首進行搜尋已經按順序檢索到了所有關鍵字。3. 使用臨時表實現GROUP BY

MySQL在進行GROUP BY操作的時候要想利用所有,必須滿足GROUP BY的欄位必須同時存放於同一個索引中,且該索引是一個有序索引(如Hash索引就不能滿足要求)。而且,並不只是如此,是否能夠利用索引來實現GROUP BY還與使用的聚合函式也有關係。

前面兩種GROUP BY的實現方式都是在有可以利用的索引的時候使用的,當MySQL Query Optimizer無法找到合適的索引可以利用的時候,就不得不先讀取需要的資料,然後通過臨時表來完成GROUP BY操作。

複製程式碼
[email protected] : example 09:02:40> EXPLAIN
-> SELECT max(gmt_create)
-> FROM group_message
-> WHERE group_id > 1 and group_id < 10
-> GROUP BY user_id\G

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: range
possible_keys: idx_group_message_gid_uid,idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: NULL
rows: 32
Extra: Using where; Using index; Using temporary; Using filesort
複製程式碼

這次的執行計劃非常明顯的告訴我們MySQL通過索引找到了我們需要的資料,然後建立了臨時表,又進行了排序操作,才得到我們需要的GROUP BY結果。整個執行過程大概如下圖所展示:

clip_image002[13] 

當MySQL Query Optimizer發現僅僅通過索引掃描並不能直接得到GROUP BY的結果之後,他就不得不選擇通過使用臨時表然後再排序的方式來實現GROUP BY了。

在這樣示例中即是這樣的情況。group_id並不是一個常量條件,而是一個範圍,而且GROUP BY欄位為user_id。所以MySQL無法根據索引的順序來幫助GROUP BY的實現,只能先通過索引範圍掃描得到需要的資料,然後將資料存入臨時表,然後再進行排序和分組操作來完成GROUP BY。

對於上面三種MySQL處理GROUP BY的方式,我們可以針對性的得出如下兩種優化思路:

1.儘可能讓MySQL可以利用索引來完成GROUP BY操作,當然最好是鬆散索引掃描的方式最佳。在系統允許的情況下,我們可以通過調整索引或者調整Query這兩種方式來達到目的;

2.當無法使用索引完成GROUP BY的時候,由於要使用到臨時表且需要filesort,所以我們必須要有足夠的sort_buffer_size來供MySQL排序的時候使用,而且儘量不要進行大結果集的GROUP BY操作,因為如果超出系統設定的臨時表大小的時候會出現將臨時表資料copy到磁碟上面再進行操作,這時候的排序分組操作效能將是成數量級的下降;

至於如何利用好這兩種思路,還需要大家在自己的實際應用場景中不斷的嘗試並測試效果,最終才能得到較佳的方案。此外,在優化GROUP BY的時候還有一個小技巧可以讓我們在有些無法利用到索引的情況下避免filesort操作,也就是在整個語句最後新增一個以null排序(ORDER BY null)的子句,大家可以嘗試一下試試看會有什麼效果。

DISTINCT 的實現與優化

DISTINCT實際上和GROUP BY的操作非常相似,只不過是在GROUP BY之後的每組中只取出一條記錄而已。所以,DISTINCT的實現和GROUP BY的實現也基本差不多,沒有太大的區別。同樣可以通過鬆散索引掃描或者是緊湊索引掃描來實現,當然,在無法僅僅使用索引即能完成DISTINCT的時候,MySQL只能通過臨時表來完成。但是,和GROUP BY有一點差別的是,DISTINCT並不需要進行排序。也就是說,在僅僅只是DISTINCT操作的Query如果無法僅僅利用索引完成操作的時候,MySQL會利用臨時表來做一次資料的“快取”,但是不會對臨時表中的資料進行filesort操作。當然,如果我們在進行DISTINCT的時候還使用了GROUP BY並進行了分組,並使用了類似於MAX之類的聚合函式操作,就無法避免filesort了。

下面我們就通過幾個簡單的Query示例來展示一下DISTINCT的實現。

1.首先看看通過鬆散索引掃描完成DISTINCT的操作:

複製程式碼
[email protected] :  example 11:03:41> EXPLAIN SELECT  DISTINCT group_id
->  FROM  group_message\G
*************************** 1.  row  ***************************
id:  1
SELECT_type: SIMPLE
table: group_message
type: range
possible_keys: NULL
key:  idx_gid_uid_gc
key_len: 4
ref:  NULL
rows: 10
Extra: Using  index for  group-by
1  row  in  set  (0.00 sec)
複製程式碼

我們可以很清晰的看到,執行計劃中的Extra資訊為“Using index for group-by”,這代表什麼意思?為什麼我沒有進行GROUP BY操作的時候,執行計劃中會告訴我這裡通過索引進行了GROUP BY呢?其實這就是於DISTINCT的實現原理相關的,在實現DISTINCT的過程中,同樣也是需要分組的,然後再從每組資料中取出一條返回給客戶端。而這裡的Extra資訊就告訴我們,MySQL利用鬆散索引掃描就完成了整個操作。當然,如果MySQL Query Optimizer要是能夠做的再人性化一點將這裡的資訊換成“Using index for distinct”那就更好更容易讓人理解了,呵呵。

2.  我們再來看看通過緊湊索引掃描的示例:

複製程式碼
[email protected] : example 11:03:53> EXPLAIN SELECT DISTINCT user_id
-> FROM group_message
-> WHERE group_id = 2\G
*************************** 1. row ***************************
id: 1
SELECT_type: SIMPLE
table: group_message
type: ref
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: const
rows: 4
Extra: Using WHERE; Using index
1 row in set (0.00 sec)
複製程式碼

這裡的顯示和通過緊湊索引掃描實現GROUP BY也完全一樣。實際上,這個Query的實現過程中,MySQL會讓儲存引擎掃描group_id=2的所有索引鍵,得出所有的user_id,然後利用索引的已排序特性,每更換一個user_id的索引鍵值的時候保留一條資訊,即可在掃描完所有gruop_id=2的索引鍵的時候完成整個DISTINCT操作。

3.下面我們在看看無法單獨使用索引即可完成DISTINCT的時候會是怎樣:

複製程式碼
[email protected] : example 11:04:40> EXPLAIN SELECT DISTINCT user_id
-> FROM group_message
-> WHERE group_id > 1 AND group_id < 10\G
*************************** 1. row ***************************
id: 1
SELECT_type: SIMPLE
table: group_message
type: range
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: NULL
rows: 32
Extra: Using WHERE; Using index; Using temporary
1 row in set (0.00 sec)
複製程式碼

當MySQL無法僅僅依賴索引即可完成DISTINCT操作的時候,就不得不使用臨時表來進行相應的操作了。但是我們可以看到,在MySQL利用臨時表來完成DISTINCT的時候,和處理GROUP BY有一點區別,就是少了filesort。實際上,在MySQL的分組演算法中,並不一定非要排序才能完成分組操作的,這一點在上面的GROUP BY優化小技巧中我已經提到過了。實際上這裡MySQL正是在沒有排序的情況下實現分組最後完成DISTINCT操作的,所以少了filesort這個排序操作。

4.最後再和GROUP BY結合試試看:

複製程式碼
[email protected] : example 11:05:06> EXPLAIN SELECT DISTINCT max(user_id)
-> FROM group_message
-> WHERE group_id > 1 AND group_id < 10
-> GROUP BY group_id\G
*************************** 1. row ***************************
id: 1
SELECT_type: SIMPLE
table: group_message
type: range
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: NULL
rows: 32
Extra: Using WHERE; Using index; Using temporary; Using filesort
1 row in set (0.00 sec)
複製程式碼

最後我們再看一下這個和GROUP BY一起使用帶有聚合函式的示例,和上面第三個示例相比,可以看到已經多了filesort排序操作了,因為我們使用了MAX函式的緣故。

對於DISTINCT的優化,和GROUP BY基本上一致的思路,關鍵在於利用好索引,在無法利用索引的時候,確保儘量不要在大結果集上面進行DISTINCT操作,磁碟上面的IO操作和記憶體中的IO操作效能完全不是一個數量級的差距。

總結

本章重點介紹了MySQL Query語句相關的效能調優的部分思路和方法,也列舉了部分的示例,希望能夠幫助讀者朋友在實際工作中開闊一點點思路。雖然本章涉及到的內容包含了最初的索引設計,到編寫高效Query語句的一些原則,以及最後對語句的除錯,但Query語句的調優遠不只這些內容。很多的調優技巧,只有到在實際的調優經驗中才會真正體會,真正把握其精髓。所以,希望各位讀者朋友能多做實驗,以理論為基礎,以事實為依據,只有這樣,才能不斷提升自己對Query調優的深入認識。

相關推薦

關於group by group by havingwhere group bygroup by order by

姓名 函數 學生 art sco 分數 現在 大於 數學 轉載:https://blog.csdn.net/qq_28007533/article/details/72859474 現有表 score name kecheng fenshu 張三

linq中order bygroup by (含lambda表示式實現)以及綜合案例

一、Linq對誰適用 linq的語法通過System.Linq下面的Enumerable類提供支援,也就是說,只要是實現了IEnumerable<T>的物件都可以使用Linq的語法來查詢。LINQ定義了大約40個查詢操作符,如select、from、in、where、group by 以及ord

mysql的order bygroup bydistinct優化

order by,group by和distinct三類操作是在mysql中經常使用的,而且都涉及到排序,所以就把這三種操作放在一起介紹。 order by的實現與優化 order by的實現有兩種方式,主要就是按用沒用到索引來區分: 1. 根據索引欄位排序,利用索引取出的

Mysql5.7中子查詢時order bygroup by合用無效的解決辦法

tro group by blog gpo html size 查詢 mysql 參考資料 環境說明: Windows10 專業版64位 MySQL5.7.20 《2015年辛星mysql教程第一本基礎操作》 P65 原文: 實踐內容: 上面的SQL語句沒

SQL Union和SQL Union All兩者用法區別效率以及與order bygroup by配合問題

SQL UNION 操作符 UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。 請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每條 SELECT 語句中的列的順序必須相同。 SQL UNION

SQL筆記四:order bygroup by

可能 出現 student sel 排序 字段 條件 count() class 1.order by 排序 使用場景:對查詢的數據結果做一個排序 語法:select 字段A,字段B,...,字段N from...order by 字段A asc(desc),字段Bas

mysql中order bygroup by的詳細區別是詳細區別

order by 排序查詢、asc升序、desc降序示例:select * from 學生表 order by 年齡 查詢學生表資訊、按年齡的升序(預設、可預設、從低到高)排列顯示也可以多條件排序、 比如 order by 年齡,成績 desc 按年齡升序排列後

mysql中order bygroup by的順序

mysql 中order by 與group by的順序 是: select from where group by order by 注意:group by 比order by先執行,order by不會對group by 內部進行排序,如果group by後只有一條記

Order bygroup by 的聯合使用 並對某一欄位中的不同結果進行重新命名和自由排序

最需要注意的一點就是 group by 必須包含在 roder by  子句中 如:       SELECT replace(replace(replace(replace(jb,'1','一級'),'2','二級'),'3','三級'),'4','四級')jb,ysxm

SQL Server: Difference between PARTITION BY and GROUP BY

func over UC between pla tar not pri text https://stackoverflow.com/questions/2404565/sql-server-difference-between-partition-by-and-grou

Java併發機制的底層實現原理

Java程式碼編譯後變成java位元組碼,位元組碼被類載入器載入到JVM裡,JVM執行位元組碼,最終需要轉化為彙編指令在CPU上執行,java中所使用的併發機制依賴於JVM的實現和CPU的執行。 2.1 volatile的應用 在多執行緒併發程式設計中,synchronized和v

partition bygroup by對比

今天大概弄懂了partition by和group by的區別聯絡。 1. group by是分組函式,partition by是分析函式(然後像sum()等是聚合函式); 2. 在執行順序上, 以下是常用sql關鍵字的優先順序 from > where > group by >

over partition bygroup by 的區別

今天看到一個老兄的問題,   大概如下:  查詢出部門的最低工資的userid 號  表結構:  D號      工資      部門  userid salary   dept  1      2000      1  2      1000      1  3    

今天認識了下partition bygroup by

今天學習Oracle  sql語句時碰到了這樣的題目: 查詢各科成績前三名的記錄:(不考慮成績並列情況) 略看題目,以為能弄出來,下手寫時才發現不是那樣的 經過一番查閱後,才知道,還有partitio

oracle分析函式over partition bygroup by的區別

今天看到一個老兄的問題, 大概如下: 查詢出部門的最低工資的userid 號 表結構: D號      工資      部門 userid salary   dept 1      2000      1 2      1000      1 3      500       2 4    

distinctorder by group by實現原理

前言 除了常規的Join語句之外,還有一類Query語句也是使用比較頻繁的,那就是ORDERBY,GROUP BY以及DISTINCT這三類查詢。考慮到這三類查詢都涉及到資料的排序等操作,所以我將他們放在了一起,下面就針對這三類Query語句做基本的分析。 ORDE

hive------ Group byjoindistinct實現原理

map etc 條件 val log in use ins none 操作 1. Hive 的 distribute by Order by 能夠預期產生完全排序的結果,但是它是通過只用一個reduce來做到這點的。所以對於大規模的數據集它的效率非常低。在很多

解析mysql中:單表distinct多表group by查詢去除重復記錄

itl lec sql 4.0 mysql clas 遺憾 join 去除 單表的唯一查詢用:distinct多表的唯一查詢用:group bydistinct 查詢多表時,left join 還有效,全連接無效,在使用mysql時,有時需要查詢出某個字段不重復的記錄,雖然

07-Hive高階查詢order bygroup by

宣告:未經本人允許,不得轉載哦! 哈嘍,大家好。這兩天就要高考了,我原本是一名物理老師,這一屆初高中的學生帶完,估計就要開始找大資料崗位的工作了。目前掌握的是技能有java+linux++mysql+hadoop+hive+hbase,正在學習的是shell,計劃2016年接著要學習

mysql中:單表distinct多表group by查詢去除重複記錄

單表的唯一查詢用:distinct 多表的唯一查詢用:group by distinct 查詢多表時,left join 還有效,全連線無效, 在使用mysql時,有時需要查詢出某個欄位不重複的記錄,雖然mysql提供有distinct這個關鍵字來過濾掉多餘的重複記錄只保留一