首页 >

groupby在sql中怎么使用? – 网络|

3d模型太大怎么优化,如何新建位图文件,qq怎么不显示图标groupby在sql中怎么使用? - 网络|groupby在sql中怎么使用

处理MySQLGROUPBY让大家看看之前看过的同一张table:mysql>showcreatetabletblG***************************1.row***************************Table:tblCreateTable:CREATETABLE`tbl`(`id`int(11)NOTNULLAUTO_INCREMENT,`k`int(11)NOTNULLDEFAULT’0′,`g`int(10)unsignedNOTNULL,PRIMARYKEY(`id`),KEY`k`(`k`))ENGINE=InnoDBAUTO_INCREMENT=2340933DEFAULTCHARSET=latin11rowinset(0.00sec)

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

1、MySQL中的IndexOrderedGROUPBY

  • mysql>selectk,count(*)cfromtblgroupbykorderbyklimit5;

  • +—+—+

  • k|c

  • +—+—+

  • 2|3

  • 4|1

  • 5|2

  • 8|1

  • 9|1

  • +—+—+

  • 5rowsinset(0.00sec)

  • mysql>explainselectk,count(*)cfromtblgroupbykorderbyklimit5G

  • ***************************1.row***************************

  • 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

  • 1rowinset,1warning(0.00sec)

  • 在这种情况下,大家在GROUPBY的列上有一个索引。这样,大家可以逐组扫描数据并动态执行GROUPBY(低成本)。当大家使用LIMIT限制大家检索的组的数量或使用“覆盖索引”时,特别有效,因为顺序索引扫描是一种非常快速的操作。
  • 如果您有少量组,并且没有覆盖索引,索引顺序扫描可能会导致大量IO。所以这可能不是最优化的计划。

  • 2、MySQL中的外部排序GROUPBY
  • mysql>explainselectSQL_BIG_RESULTg,count(*)cfromtblgroupbyglimit5G

  • ***************************1.row***************************

  • id:1

  • select_type:SIMPLE

  • table:tbl

  • partitions:NULL

  • type:ALL

  • possible_keys:NULL

  • key:NULL

  • key_len:NULL

  • ref:NULL

  • rows:998490

  • filtered:100.00

  • Extra:Usingfilesort

  • 1rowinset,1warning(0.00sec)

  • mysql>selectSQL_BIG_RESULTg,count(*)cfromtblgroupbyglimit5;

  • +—+—+

  • g|c

  • +—+—+

  • 0|1

  • 1|2

  • 4|1

  • 5|1

  • 6|2

  • +—+—+

  • 5rowsinset(0.88sec)

  • 如果大家没有允许大家按组顺序扫描数据的索引,大家可以通过外部排序(在MySQL中也称为“filesort”)来获取数据。你可能会注意到偶在这里使用SQL_BIG_RESULT提示来获得这个计划。没有它,MySQL在这种情况下不会选择这个计划。
  • 一般来说,MySQL只有在大家拥有大量组时才更喜欢使用这个计划,因为在这种情况下,排序比拥有临时表更有效(大家将在下面讨论)。

  • 3、MySQL中的临时表GROUPBY
  • mysql>explainselectg,sum(g)sfromtblgroupbyglimit5G

  • ***************************1.row***************************

  • id:1

  • select_type:SIMPLE

  • table:tbl

  • partitions:NULL

  • type:ALL

  • possible_keys:NULL

  • key:NULL

  • key_len:NULL

  • ref:NULL

  • rows:998490

  • filtered:100.00

  • Extra:Usingtemporary

  • 1rowinset,1warning(0.00sec)

  • mysql>selectg,sum(g)sfromtblgroupbygorderbynulllimit5;

  • +—+——+

  • g|s

  • +—+——+

  • 0|0

  • 1|2

  • 4|4

  • 5|5

  • 6|12

  • +—+——+

  • 5rowsinset(7.75sec)

  • 在这种情况下,MySQL也会进行全表扫描。但它不是运行额外的排序传递,而是创建一个临时表。此临时表每组包含一行,并且对于每个传入行,将更新相应组的值。很多更新!虽然这在内存中可能是合理的,但如果结果表太大以至于更新将导致大量磁盘IO,则会变得非常昂贵。在这种情况下,外部分拣计划通常更好。请注意,虽然MySQL默认选择此计划用于此用例,但如果大家不提供任何提示,它几乎比大家使用SQL_BIG_RESULT提示的计划慢10倍。您可能会注意到偶在此查询中添加了“ORDERBYNULL”。这是为了向您展示“清理”临时表的唯一计划。没有它,大家得到这个计划:mysql>explainselectg,sum(g)sfromtblgroupbyglimit5G***************************1.row***************************id:1select_type:SIMPLEtable:tblpartitions:NULLtype:ALLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:998490filtered:100.00Extra:Usingtemporary;Usingfilesort1rowinset,1warning(0.00sec)
  • 在其中,大家获得了temporary和filesort“两最糟糕的”提示。MySQL5.7总是返回按组顺序排序的GROUPBY结果,即使查询不需要它(这可能需要昂贵的额外排序传递)。ORDERBYNULL表示应用程序不需要这个。您应该注意,在某些情况下-例如使用聚合函数访问不同表中的列的JOIN查询-使用GROUPBY的临时表可能是唯一的选择。
  • 如果要强制MySQL使用为GROUPBY执行临时表的计划,可以使用SQL_SMALL_RESULT提示。

  • 4、MySQL中的索引基于跳过扫描的GROUPBY前三个GROUPBY执行方法适用于所有聚合函数。然而,其中一些人有第四种方法。
  • mysql>explainselectk,max(id)fromtblgroupbykG

  • ***************************1.row***************************

  • id:1

  • select_type:SIMPLE

  • table:tbl

  • partitions:NULL

  • type:range

  • possible_keys:k

  • key:k

  • key_len:4

  • ref:NULL

  • rows:2

  • filtered:100.00

  • Extra:Usingindexforgroup-by

  • 1rowinset,1warning(0.00sec)

  • mysql>selectk,max(id)fromtblgroupbyk;

  • +—+———+

  • k|max(id)

  • +—+———+

  • 0|2340920

  • 1|2340916

  • 2|2340932

  • 3|2340928

  • 4|2340924

  • +—+———+

  • 5rowsinset(0.00sec)

  • 此方法仅适用于非常特殊的聚合函数:MIN()和MAX()。这些并不需要遍历组中的所有行来计算值。他们可以直接跳转到组中的最小或最大组值(如果有这样的索引)。如果索引仅建立在(K)列上,如何找到每个组的MAX(ID)值?这是一个InnoDB表。记住InnoDB表有效地将PRIMARYKEY附加到所有索引。(K)变为(K,ID),允许大家对此查询使用Skip-Scan优化。仅当每个组有大量行时才会启用此优化。否则,MySQL更倾向于使用更传统的方法来执行此查询(如方法#1中详述的索引有序GROUPBY)。虽然大家使用MIN()/MAX()聚合函数,但其他优化也适用于它们。例如,如果您有一个没有GROUPBY的聚合函数(实际上所有表都有一个组),MySQL在统计分析阶段从索引中获取这些值,并避免在执行阶段完全读取表:mysql>explainselectmax(k)fromtblG***************************1.row***************************id:1select_type:SIMPLEtable:NULLpartitions:NULLtype:NULLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:NULLfiltered:NULLExtra:Selecttablesoptimizedaway1rowinset,1warning(0.00sec)
  • 过滤和分组

  • 大家已经研究了MySQL执行GROUPBY的四种方式。为简单起见,偶在整个表上使用了GROUPBY,没有应用过滤。当您有WHERE子句时,相同的概念适用:mysql>explainselectg,sum(g)sfromtblwherek>4groupbygorderbyNULLlimit5G***************************1.row***************************id:1select_type:SIMPLEtable:tblpartitions:NULLtype:rangepossible_keys:kkey:kkey_len:4ref:NULLrows:1filtered:100.00Extra:Usingindexcondition;Usingtemporary1rowinset,1warning(0.00sec)
  • 对于这种情况,大家使用K列上的范围进行数据过滤/查找,并在有临时表时执行GROUPBY。在某些情况下,方法不会发生冲突。但是,在其他情况下,大家必须选择使用GROUPBY的一个索引或其他索引进行过滤:
  • mysql>altertabletbladdkey(g);

  • QueryOK,0rowsaffected(4.17sec)

  • Records:0Duplicates:0Warnings:0

  • mysql>explainselectg,sum(g)sfromtblwherek>1groupbyglimit5G

  • ***************************1.row***************************

  • id:1

  • select_type:SIMPLE

  • table:tbl

  • partitions:NULL

  • type:index

  • possible_keys:k,g

  • key:g

  • key_len:4

  • ref:NULL

  • rows:16

  • filtered:50.00

  • Extra:Usingwhere

  • 1rowinset,1warning(0.00sec)

  • mysql>explainselectg,sum(g)sfromtblwherek>4groupbyglimit5G

  • ***************************1.row***************************

  • id:1

  • select_type:SIMPLE

  • table:tbl

  • partitions:NULL

  • type:range

  • possible_keys:k,g

  • key:k

  • key_len:4

  • ref:NULL

  • rows:1

  • filtered:100.00

  • Extra:Usingindexcondition;Usingtemporary;Usingfilesort

  • 1rowinset,1warning(0.00sec)

  • 根据此查询中使用的特定常量,大家可以看到大家对GROUPBY使用索引顺序扫描(并从索引中“放弃”以解析WHERE子句),或者使用索引来解析WHERE子句(但使用临时表来解析GROUPBY)。根据偶的经验,这就是MySQLGROUPBY并不总是做出正确选择的地方。您可能需要使用FORCEINDEX以您希望的方式执行查询。

groupby在sql中怎么使用? - 网络|
  • 学习python具体要学习哪些内容?去哪学习好? |python web 项目经验
  • 学习python具体要学习哪些内容?去哪学习好? |python web 项目经验 | 学习python具体要学习哪些内容?去哪学习好? |python web 项目经验 ...

    groupby在sql中怎么使用? - 网络|
  • 本人大一,下学期刚学了JAVA,只跟着老师学习课本JAVA2实用教程,想自学,第一本书应该看什么? - 网络|
  • 本人大一,下学期刚学了JAVA,只跟着老师学习课本JAVA2实用教程,想自学,第一本书应该看什么? - 网络| | 本人大一,下学期刚学了JAVA,只跟着老师学习课本JAVA2实用教程,想自学,第一本书应该看什么? - 网络| ...

    groupby在sql中怎么使用? - 网络|
  • 网上视频剪辑软件附带好多垃圾软件,求几款好用的视频剪辑软件? - 网络|
  • 网上视频剪辑软件附带好多垃圾软件,求几款好用的视频剪辑软件? - 网络| | 网上视频剪辑软件附带好多垃圾软件,求几款好用的视频剪辑软件? - 网络| ...