推广 热搜: 广场  Java  app  Word  营业  微信公众号  北京代理记账  商城  代理记账  商标交易 

mysql行转列多条件查询 mysql为什么group by不能显示全部数据?

   2023-04-27 企业服务招财猫100
核心提示:mysql为什么groupby不能显示全部数据?在日常查询中,索引或其他数据查找方法可能不是查询执行中开销最大的部分。例如,MySQLGROUPBY可能负责90%以上的查询执行时间。MySQL执行GR

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

在日常查询中,索引或其他数据查找方法可能不是查询执行中开销最大的部分。例如,MySQLGROUPBY可能负责90%以上的查询执行时间。MySQL执行GROUPBY的主要复杂度是计算GROUPBY语句中的聚合函数。UDF聚合函数是逐个获取组成单个组的所有值。这样,它可以在移动到另一个组之前计算单个组的聚合函数值。当然,问题是在大多数情况下,源数据值没有分组。不同组的值在处理过程中会相互跟随。因此,我们需要一个特殊的步骤。

用Letamp处理MySQL组。;让我们再来看一下我们之前见过的同一个表:MySQLshowcr:TBL创建Tabl:创建表`TBL`(`id`int(11)NOTNULLAUTO_INCREMENT,`k`int(11)NOTNULLDEFAULT0,`g`int(10)unsignedNOTNULL,PRIMARYKEY(`id`),KEY`k`(`k`))ENGINEInnoDBAUTO_incremENT2340933DEFAULTcharsetlatin1集合中的第1行(0.00秒)

并以不同的执行相同的GROUPBY语句:

中的索引排序分组。

mysqlselectk,count(*)cfromTBLgroupbykorderbyklimit5;

--

|k|c|

--

|2|3|

|4|1|

|5|2|

|8|1|

|9|1|

--

一组5行(0.00秒)

mysql解释selectk,count(*)cfromTBLgroupbykord:1号

select_typ:简单

tabl:TBL

partitions:零

typ:指数

possibl:·k

k:·k

k:4

r:零

rows:5

filt:100.00

:使用指数

集合中的1行,1个警告(0.00秒)

在这种情况下,我们在GROUPBY列上有一个索引。这样我们就可以一组一组的扫描数据,动态的执行GROUPBY(低成本)。当我们使用LIMIT来限制我们检索或使用的组的数量时,这尤其有效覆盖索引",因为顺序索引扫描是一种非常快速的操作。

如果您有少量的组并且不覆盖索引,索引顺序扫描可能会导致大量的IO。所以这可能不是最优方案。

中的外部排序分组依据

mysql解释selectSQL_BIG_RESULTg,count(*)cfromTBLgroupbyGlimit5g

***************************1.第*************************行

id:1号

select_typ:简单

tabl:TBL

partitions:零

typ:所有

possibl:零

k:零

k:零

r:零

rows:998490

filt:100.00

使用文件排序的:

集合中的1行,1个警告(0.00秒)

mysqlselectSQL_BIG_RESULTg,count(*)cfromTBLgroupbyglimit5;

--

|g|c|

--

|0|1|

|1|2|

|4|1|

|5|1|

|6|2|

--

一组5行(0.88秒)

如果我们不这样做。;如果没有允许我们按组顺序扫描数据的索引,我们可以通过外部排序(也称为"文件排序和在MySQL中)。您可能会注意到,我在这里使用SQL_BIG_RESULT提示符来获得这个计划。如果没有它,MySQL在这种情况下也不会选择这个方案。

一般来说,只有当我们有大量的组时,MySQL更喜欢使用这种计划,因为在这种情况下,排序比拥有临时表(我们将在下面讨论)更有效。

中的临时表GROUPBY

mysql解释selectg,sum(g)sfromtblgroupbyglimit5G

***************************1.第*************************行

id:1号

select_typ:简单

tabl:TBL

partitions:零

typ:所有

possibl:零

k:零

k:零

r:零

rows:998490

filt:100.00

:使用临时

集合中的1行,1个警告(0.00秒)

mysqlselectg,sum(g)sfrommTBLgroupbygorderbynulllimit5;

--

|g|s|

--

|0|0|

|1|2|

|4|4|

|5|5|

|6|12|

--

一组5行(7.75秒)

在这种情况下,MySQL也会执行全表扫描。但是它不是运行额外的排序过程,而是创建一个临时表。这个临时表在每个组中包含一行,对于每个传入的行,相应组的值将被更新。很多更新!虽然这在内存上可能是合理的,但是如果结果表非常大,以至于更新会导致大量的磁盘IO,那么它就变得非常昂贵。在这种情况下,外部排序计划通常更好。请注意,尽管MySQL默认为这个用例选择了这个计划,但是如果我们不不提供任何提示,它几乎比我们使用SQL_BIG_RESULT提示的计划慢10倍。你可能注意到我加了"按空值排序这个问题。这是向你展示的唯一计划清理"临时桌子。没有它,我们得到这个方案:mysqlexplainselectg,sum(G)sfromTBLgroupbyGlimit5g***********************1。排*************************id:1select_typ:简单tabl:TBLpartitions:NULLtyp:ALLpossible_keysecNULLk:NULLk:NULLr:NULLrows:998490filt:100.00:使用临时;使用文件对集合中的1行进行排序,1次警告(0.00秒)

其中,我们得到了"两个最坏的"来自临时和文件分类的提示。。MySQL5.7总是返回按分组顺序排序的分组结果,即使查询没有。;我不需要它(这可能需要昂贵的额外排序过程)。ORD:1号

select_typ:简单

tabl:TBL

partitions:零

typ:山脉

possibl:·k

k:·k

k:4

r:零

rows:2

filt:100.00

:使用索引进行分组

集合中的1行,1个警告(0.00秒)

mysql通过k从tbl组中选择k,max(id);

--

|k|最大值(id)|

--

|0|2340920|

|1|2340916|

|2|2340932|

|3|2340928|

|4|2340924|

--

一组5行(0.00秒)

这个方法只适用于非常特殊的聚合函数:MIN()和m。AX().这些不需要遍历组中的所有行来计算值。它们可以直接跳转到组中的最小或最大组值(如果有这样的索引)。如果索引只建立在列(k)上,如何找到每个组的MAX(ID)值?这是一个InnoDB表。请记住,InnoDB表有效地将主键附加到所有索引上。(K)变成(K,ID),这允许我们对这个查询使用跳过扫描优化。只有当每组有大量行时,才会启用这种优化。否则,MySQL更喜欢使用更传统的方法来执行这个查询(比如方法#1中详述的索引有序分组)。虽然我们使用MIN()/MAX()聚合函数,但其他优化也适用于它们。例如,如果有一个没有GROUPBY的聚合函数(事实上,所有的表都有一个GROUP),MySQL在统计分析阶段从索引中获取这些值。并避免在执行阶段完全读表:MySQLexplainselectmax(k)来自TBLG*********************1。第*************行。id:1select_typ:简单tabl:NULLpartitions:NULLtyp:NULLpossibl:NULLk:NULLk:NULLr:NULLrows:NULLfilt:NULL:Selecttables优化了集合中的1行,1个警告(0.00秒)

过滤和分组

我们已经研究了MySQL执行GROUPBY的四种。为了简单起见,我在整个表上使用了GROUPBY,并且没有应用过滤。当你有一个WHERE子句时,同样的概念也适用:MySQLexplainselectg,sum(G)sfromTBLWH:1select_typ:简单tabl:TBLpartitions:NULLtyp:范围可能_k:kk:kk:4r:NULLrows:1filt:100.00:使用索引条件;使用集合中的临时1行,1个警告(0.00秒)

在这种情况下,我们使用K列上的范围进行数据过滤/查找,并在有临时表时执行GROUPBY。在某些情况下,方法并不。但是,在其他情况下,我们必须选择使用GROUPBY索引或其他索引进行筛选:

MySQLaltertableTBLaddkey(g);

查询正常,0行受影响(4.17秒)

Records:0Duplicat:0Warnings:0

mysql解释selectg,sum(g)sfromtbl其中k1groupbyg限制5G

***************************1.第*************************行

id:1号

select_typ:简单

tabl:TBL

partitions:零

typ:指数

possibl:k,g

k:g

k:4

r:零

rows:16

filt:50.00

:用在哪里

集合中的1行,1个警告(0.00秒)

mysql解释selectg,sum(G)sfromTBLwh:1号

select_typ:简单

tabl:TBL

partitions:零

typ:山脉

possibl:公司

k:·k

k:4

r:零

rows:1号

filt:100.00

:使用索引条件;使用临时;使用文件排序

集合中的1行,1个警告(0.00秒)

根据该查询中使用的特定常量,我们可以看到我们使用了索引顺序扫描(和"丢弃"从索引解析WHERE子句)或使用索引解析WHERE子句(但使用临时表解析GROUPBY)。根据我的经验,这就是MySQLGROUPBYdoesn不要总是做出正确的选择。您可能需要使用FORC

mysql主键的列可以再添加索引吗?

看你的节目。如果查询条件中没有使用主键,可以将查询字段设置为索引。如果你想在主键上设置一个索引,你不用我不需要它。主键具有索引的功能。

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
合作伙伴
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  冀ICP备2023006999号-8