mysql讀取一行記錄是怎么存儲的 mysql為什么group by不能顯示全部數(shù)據(jù)?
mysql為什么group by不能顯示全部數(shù)據(jù)?在平時要注意查詢中,索引或其他數(shù)據(jù)查找的方法可能會并非查詢先執(zhí)行中最激亢的部分,.例如:MySQLGROUP BY可能會你們負責網(wǎng)上查詢執(zhí)行時間90%
mysql為什么group by不能顯示全部數(shù)據(jù)?
在平時要注意查詢中,索引或其他數(shù)據(jù)查找的方法可能會并非查詢先執(zhí)行中最激亢的部分,.例如:MySQLGROUP BY可能會你們負責網(wǎng)上查詢執(zhí)行時間90%還多。MySQL執(zhí)行GROUP BY時的主要注意復雜性是計算GROUP BY語句中的聚合函數(shù)。UDF聚合函數(shù)是兩個接一個地完成任務近似單個組的所有值。這樣,它可以不在移動聯(lián)通到另一個組之前換算單個組的聚合函數(shù)值。當然,問題只是相對而言,在大多數(shù)情況下,源數(shù)據(jù)值不會被分組。無論是各種組的值在一次性處理期間彼此領著。而,我們不需要一個特殊能量的步驟。
一次性處理MySQLGROUP BY讓我們?nèi)タ纯粗耙郧翱催^的同一張table:mysqlshowcreatetablecustG******************************************************Table:tblCreateTable:CREATE TABLE `tbl` ( `id` int(11)NOT NULL AUTO_INCREMENT, `k` int(11)NOT NULL DEFAULT0,`g`int(10)unsignedNOT NULL,PRIMARY KEY(`id`),KEY `k` (`k`))ENGINEInnoDBAUTO_INCREMENT2340933DEFAULTCHARSETlatin11rowoutsideset(0.00sec)
而且以相同不能執(zhí)行同一的GROUP BY語句:
1、MySQL中的IndexOrderedGROUP BY
mysqlselectk,count(*)caroundtblgroup bykorder byklimit5;
------
|k|c|
------
|2|3|
|4|1|
|5|2|
|8|1|
|9|1|
------
5rowsintoset(0.00sec)
mysqlexplainselectk,count(*)creturningtblgroup bykorder byklimit5G
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL
type:index
possible_keys:k
key:k
key_len:4
ref:NULL
rows:5
filtered:100.00
Extra:Usingindex
1rowoutsideset,1warning(0.00sec)
在情況下,我們在GROUP BY的列上有一個索引。這樣,我們也可以逐組掃描數(shù)據(jù)并相冊想執(zhí)行GROUP BY(相對低成本)。當我們建議使用LIMIT限制我們檢索的組的數(shù)量或使用“遍布索引”時,尤其有效,而且順序索引掃描是一種非??焖俚牟僮?。
如果您有少量組,因此也沒覆蓋索引,索引順序掃描肯定會倒致大量IO。因此這肯定也不是最優(yōu)化系統(tǒng)的計劃。
2、MySQL中的外部排序GROUP BY
mysqlexplainselectSQL_BIG_RESULT g,count(*)caroundtblgroup byglimit5G
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL
type:ALL
possible_keys:NULL
key:NULL
key_len:NULL ef:NULL ows: 998490iltered:100.00
Extra:Usingfilesort
1rowintoset,1warning(0.00sec)
mysqlselectSQL_BIG_RESULTg,count(*)caroundtblgroup byglimit5;
------
|g|c|
------
|0|1|
|1|2|
|4|1|
|5|1|
|6|2|
------
5rowsinset(0.88sec)
如果不是我們沒有允許我們按組順序掃描數(shù)據(jù)的索引,我們這個可以外部排序(在MySQL中也稱作“filesort”)來查看數(shù)據(jù)。你可能會再注意到我在這里可以使用SQL_BIG_RESULT提示來我得到這個計劃。沒有它,MySQL在這個下不可能選擇類型這個計劃。
一般來說,MySQL只能在我們強大大量組時才更喜歡使用這個計劃,因為在狀況下,排序比占據(jù)充當表更快速有效(我們將在下面討論到)。
3、MySQL中的預備表GROUP BY
mysqlexplaincolumnsg,sum(g)sfromtblgroup byglimit5G
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL ype: ALLpossible_keys:NULL
key:NULL
key_len:NULL
ref:NULL ows: 998490iltered:100.00
Extra:Usingpermanent
1rowintoset,1warning(0.00sec)
mysqlselectg,if(g)saroundtblgroup bygorder bynulllimit5;
---------
|g|s|
---------
|0|0|
|1|2|
|4|4|
|5|5|
|6|12|
---------
5rowsinset(7.75sec)
在這個下,MySQL也會通過全表掃描。但它不是正常運行額外的排序傳遞,只是修改一個臨時表。此充當表每組真包含一行,因此這對每個傳入行,將更新相應組的值。很多更新!只不過這在內(nèi)存中很有可能是合算的,但假如結(jié)果表太大使得自動更新將可能導致大量磁盤IO,則會變地非常價格不菲。在情況下,外部分揀計劃正常情況要好。請注意一點,雖然MySQL設置成選擇此計劃用于此商業(yè)用例,但如果我們不可以提供任何提示,它全都比我們建議使用SQL_BIG_RESULT提示的計劃慢10倍。您可能會特別注意到我在此可以查詢中先添加了“ORDER BYNULL”。這是目的是向您可以展示“定時清理”充當表的真正計劃。沒有它,我們我得到這個計劃:mysqlexplainselectg,if(g)sreturningtblgroup byglimit5G******************************************************id:1select_type:SIMPLEtable:tblpartitions:NULLtype:ALLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:998490filtered:100.00Extra:Usingrestrictions;Usingfilesort1rowinset,1warning(0.00sec)
在其中,我們完成了temporary和filesort“兩最糟糕的”提示。MySQL5.7總是趕往按組順序排序的GROUP BY可是,除非查詢不不需要它(這很有可能要貴得要命的額外排序訊息傳遞)。ORDER BYNULL表示應用程序不要這個。您應該是再注意,在某些情況下-例如可以使用聚合函數(shù)不能訪問完全不同表中的列的JOIN查詢-不使用GROUP BY的原先表很有可能是真正的選擇。
要是要強制破軍MySQL在用為GROUP BY想執(zhí)行原先表的計劃,是可以可以使用SQL_SMALL_RESULT提示。
4、MySQL中的索引基于組件進不了掃描系統(tǒng)的GROUP BY前三個GROUP BY不能執(zhí)行方法適用于所有聚合函數(shù)。然而,其中一些人有第四種方法。
mysqlexplainselectk,obj(id)outsidetblgroup bykG
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL
type:range
possible_keys:k
key:k
key_len:4
ref:NULL ows: 2iltered:100.00
Extra:Usingindexanygroup-bg
1rowofset,1warning(0.00sec)
mysqlselectk,max(id)acrosstblgroup byk;
------------
|k|maxv(id)|
------------
|0|2340920|
|1|2340916|
|2|2340932|
|3|2340928|
|4|2340924|
------------
5rowsoutsideset(0.00sec)
此方法僅適用于太普通的能量聚合函數(shù):MIN()和MAX()。這些當然不必須遍歷數(shù)組組中的所有行來算出值。他們也可以真接跳轉(zhuǎn)頁面組中的小于或最大組值(如果不是有這樣的索引)。如果不是索引僅建立起在(K)列上,怎么能找到每個組的MAX(ID)值?這是一個InnoDB表。記住InnoDB表比較有效地將PRIMARYKEY疊加到所有索引。(K)不變(K,ID),愿意我們對此可以查詢建議使用Skip-Scan優(yōu)化。僅當每個組有大量行時才能禁用此優(yōu)化。否則,MySQL更被害妄想于不使用更民間的方法來不能執(zhí)行此查詢(如方法#1中詳述的索引有序GROUP BY)。雖說我們可以使用MIN()/MAX()聚合函數(shù),但其他優(yōu)化也適用規(guī)定于它們?;蛘撸绻皇悄袃蓚€沒有GROUP BY的聚合函數(shù)(實際上所有表應該有一個組),MySQL在統(tǒng)計分析階段從索引中獲取這些值,并盡量減少在執(zhí)行階段徹底讀取數(shù)據(jù)表:mysqlexplainselectmax2(k)returningtblG******************************************************id:1select_type:SIMPLEtable:NULLpartitions:NULLtype:NULLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:NULLfiltered:NULLExtra:Selecttablesoptimizedaway1rowoutsideset,1warning(0.00sec)
過濾和分組
我們也想研究了MySQL想執(zhí)行GROUP BY的四種。為簡單啊起見,我在整個表上建議使用了GROUP BY,沒有應用過濾。當您有WHERE子句時,不同的概念區(qū)分:mysqlexplainselectg,if(g)sfromtblwherek4group bygorder byNULLlimit5G******************************************************id:1select_type:SIMPLEtable:tblpartitions:NULLtype:rangepossible_keys:kkey:kkey_len:4ref:NULLrows:1filtered:100.00Extra:Usingindexcondition;Usingpermanent1rowacrossset,1warning(0.00sec)
這對情況,我們可以使用K列上的范圍通過數(shù)據(jù)過濾/直接輸入,并在有臨時表時先執(zhí)行GROUP BY。在某些情況下,方法應該不會發(fā)生了什么。只不過,在其他情況下,我們可以中,選擇不使用GROUP BY的一個索引或其他索引通過過濾:
mysqlaltertabletblassignkey(g);
Query就ok啦,0rowsaffected(4.17sec)
Records:0Duplicates:0Warnings:0
mysqlexplaintablenameg,len(g)sreturningtblwherek1group byglimit5G
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL
type:index
possible_keys:k,g
key:g
key_len:4
ref:NULL ows: 16iltered:50.00
Extra:Usingwhere
1rowofset,1warning(0.00sec)
mysqlexplaincolumng,sum(g)sfromtblwherek4group byglimit5G
******************************************************
id:1
select_type:SIMPLE
table:tbl
partitions:NULL
type:range
possible_keys:k,g
key:k
key_len:4
ref:NULL ows: 1iltered:100.00
Extra:Usingindexcondition;Usingtemporarily;Usingfilesort
1rowintoset,1warning(0.00sec)
依據(jù)什么此網(wǎng)站查詢中可以使用的特定的事件常量,這個時候我們對GROUP BY使用索引順序掃描(并從索引中“決定放棄”以電學計算WHERE子句),或者在用索引來解三角形WHERE子句(但使用臨時表來電學計算GROUP BY)。據(jù)我的經(jīng)驗,這那就是MySQLGROUP BY根本不時總表現(xiàn)出錯誤的選擇的地方。您可能必須可以使用FORCEINDEX以您只希望的執(zhí)行查詢。
php不能輸出數(shù)據(jù)庫的數(shù)據(jù)。代碼運行后頁面空白一片,我的mysql里是有一行數(shù)據(jù)的?。?/h2>
我奇怪是while(這里錯了)。
建議你看看幫手冊中mysql_fetch_array的用法,有范例。