2016 - 2024

感恩一路有你

mysql读取一行记录是怎么存储的 mysql为什么group by不能显示全部数据?

浏览量:1112 时间:2023-07-12 23:40:50 作者:采采

mysql为什么group by不能显示全部数据?

在平时要注意查询中,索引或其他数据查找的方法可能会并非查询先执行中最激亢的部分,.例如:MySQLGROUP BY可能会你们负责网上查询执行时间90%还多。MySQL执行GROUP BY时的主要注意复杂性是计算GROUP BY语句中的聚合函数。UDF聚合函数是两个接一个地完成任务近似单个组的所有值。这样,它可以不在移动联通到另一个组之前换算单个组的聚合函数值。当然,问题只是相对而言,在大多数情况下,源数据值不会被分组。无论是各种组的值在一次性处理期间彼此领着。而,我们不需要一个特殊能量的步骤。

一次性处理MySQLGROUP BY让我们去看看之前以前看过的同一张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)

而且以相同不能执行同一的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的列上有一个索引。这样,我们也可以逐组扫描数据并相册想执行GROUP BY(相对低成本)。当我们建议使用LIMIT限制我们检索的组的数量或使用“遍布索引”时,尤其有效,而且顺序索引扫描是一种非常快速的操作。

如果您有少量组,因此也没覆盖索引,索引顺序扫描肯定会倒致大量IO。因此这肯定也不是最优化系统的计划。

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: 998490 iltered: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)

如果不是我们没有允许我们按组顺序扫描数据的索引,我们这个可以外部排序(在MySQL中也称作“filesort”)来查看数据。你可能会再注意到我在这里可以使用SQL_BIG_RESULT提示来我得到这个计划。没有它,MySQL在这个下不可能选择类型这个计划。

一般来说,MySQL只能在我们强大大量组时才更喜欢使用这个计划,因为在状况下,排序比占据充当表更快速有效(我们将在下面讨论到)。

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: 998490 iltered: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也会通过全表扫描。但它不是正常运行额外的排序传递,只是修改一个临时表。此充当表每组真包含一行,因此这对每个传入行,将更新相应组的值。很多更新!只不过这在内存中很有可能是合算的,但假如结果表太大使得自动更新将可能导致大量磁盘IO,则会变地非常价格不菲。在情况下,外部分拣计划正常情况要好。请注意一点,虽然MySQL设置成选择此计划用于此商业用例,但如果我们不可以提供任何提示,它全都比我们建议使用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表示应用程序不要这个。您应该是再注意,在某些情况下-例如可以使用聚合函数不能访问完全不同表中的列的JOIN查询-不使用GROUP BY的原先表很有可能是真正的选择。

要是要强制破军MySQL在用为GROUP BY想执行原先表的计划,是可以可以使用SQL_SMALL_RESULT提示。

4、MySQL中的索引基于组件进不了扫描系统的GROUP BY前三个GROUP BY不能执行方法适用于所有聚合函数。然而,其中一些人有第四种方法。

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: 2 iltered: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)

此方法仅适用于太普通的能量聚合函数:MIN()和MAX()。这些当然不必须遍历数组组中的所有行来算出值。他们也可以真接跳转页面组中的小于或最大组值(如果不是有这样的索引)。如果不是索引仅建立起在(K)列上,怎么能找到每个组的MAX(ID)值?这是一个InnoDB表。记住InnoDB表比较有效地将PRIMARYKEY叠加到所有索引。(K)不变(K,ID),愿意我们对此可以查询建议使用Skip-Scan优化。仅当每个组有大量行时才能禁用此优化。否则,MySQL更被害妄想于不使用更民间的方法来不能执行此查询(如方法#1中详述的索引有序GROUP BY)。虽说我们可以使用MIN()/MAX()聚合函数,但其他优化也适用规定于它们。或者,如果不是您有两个没有GROUP BY的聚合函数(实际上所有表应该有一个组),MySQL在统计分析阶段从索引中获取这些值,并尽量减少在执行阶段彻底读取数据表:mysqlexplainselectmax2(k)returningtblG******************************************************id:1select_type:SIMPLEtable:NULLpartitions:NULLtype:NULLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:NULLfiltered:NULLExtra:Selecttablesoptimizedaway1rowoutsideset,1warning(0.00sec)

过滤和分组

我们也想研究了MySQL想执行GROUP BY的四种。为简单啊起见,我在整个表上建议使用了GROUP BY,没有应用过滤。当您有WHERE子句时,不同的概念区分: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列上的范围通过数据过滤/直接输入,并在有临时表时先执行GROUP BY。在某些情况下,方法应该不会发生了什么。只不过,在其他情况下,我们可以中,选择不使用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: 16 iltered: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: 1 iltered:100.00

Extra:Usingindexcondition;Usingtemporarily;Usingfilesort

1rowintoset,1warning(0.00sec)

依据什么此网站查询中可以使用的特定的事件常量,这个时候我们对GROUP BY使用索引顺序扫描(并从索引中“决定放弃”以电学计算WHERE子句),或者在用索引来解三角形WHERE子句(但使用临时表来电学计算GROUP BY)。据我的经验,这那就是MySQLGROUP BY根本不时总表现出错误的选择的地方。您可能必须可以使用FORCEINDEX以您只希望的执行查询。

php不能输出数据库的数据。代码运行后页面空白一片,我的mysql里是有一行数据的啊?

我奇怪是while(这里错了)。

建议你看看帮手册中mysql_fetch_array的用法,有范例。

GROUP BY 0.00sec MySQL 数据

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。