mysql 分組查詢原理,MySQL分組查詢Group By實現原理詳解

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

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

1、使用松散(Loose)索引掃描實現 GROUP BY

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

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

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

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

下面這張圖片描繪了掃描過程的大概實現:

2e4db0dba005debf42eda4527aae6e80.png

要利用到松散索引掃描實現 GROUP BY,需要至少滿足以下幾個條件:

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

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

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

為什么松散索引掃描的效率會很高?

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

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

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

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

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

8dcc6d5bb1aea75a3d5f665c06a986a7.png

在 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 操作。

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

40a9c0ce5a689d620493ff5c6455e7cd.png

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533201.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533201.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533201.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql 執行計劃詳解,Mysql中的explain執行計劃詳解(1)

創建一個表test_explain,并添加入下的數據mysql> create table test_explain( a int primary key, b int);Query OK, 0 rows affected (0.09 sec)mysql> insert into test_explain value(1,1),(2,2),(3,3),(4,4),(5,5);explian中的type字段:表示m…

mac php命令行模式,phpstorm分別在Mac和Windows下啟動命令行,并啟用ssh

Mac:在terminal下運行 sudo -i 輸入密碼 就可以用ssh IP:端口 命令行登錄了DAssist是一個命令行開發輔助,可直接在系統命令行工具中使用,Linux和MacOS等自帶命令終端的系統好說,windows下也有cmd和powerShell。那么如何結合開發IDE工具進行…

matlab 價格統計,matlab中的金融數據統計

1.均勻分布隨機數生成函數unidrnd(N,m,n)N生成1到N之間的一個隨機數,確定輸出矩陣m行,n列。2.生成連續均勻分布的隨機數unifrnd(A,B,m,n)A,B表示上下界。3.生成正態分布隨機數normrnd(mu,sigma,m,n)mu均值,…

php訪問js文件不存在,php文件里js不能被執行

我想把上傳文件路徑返回到前端保存&#xff0c;但是后臺php文件里的js沒有執行&#xff0c;前臺input標簽里的value值一直為空后臺acceptfile.php代碼如下:<?php if(!isset($_REQUEST[filename])){exit(No file);}else{$upload_path dirname(__FILE__)./audio;date_defaul…

php 零寬斷言,正則表達式之零寬斷言實例詳解【基于PHP】

這篇文章主要介紹了正則表達式之零寬斷言,簡單介紹了零寬斷言的概念、分類及php實現技巧與相關注意事項,需要的朋友可以參考下本文實例講述了正則表達式之零寬斷言。分享給大家供大家參考&#xff0c;具體如下&#xff1a;前言之前我曾寫了一篇關于正則表達式的文章(//www.jb51…

python 邏輯回歸準確率是1,Python利用邏輯回歸模型解決MNIST手寫數字識別問題詳解...

本文實例講述了Python利用邏輯回歸模型解決MNIST手寫數字識別問題。分享給大家供大家參考&#xff0c;具體如下&#xff1a;1、MNIST手寫識別問題MNIST手寫數字識別問題&#xff1a;輸入黑白的手寫阿拉伯數字&#xff0c;通過機器學習判斷輸入的是幾。可以通過TensorFLow下載MN…

php面試題接口方面,php面試題6 - osc_xb4v1nhl的個人空間 - OSCHINA - 中文開源技術交流社區...

php面試題6一、總結二、php面試題6寫出你認為語言中的高級函數:1)preg_replace()2)preg_match()3) ignore_user_abort()4) debug_backtrace()5) date_default_timezone_set(“PRC”)6) get_class_methods() 得到類的方法名的數組7) preg_split() 字符串分割成數組8)json_encode…

軌道車輛垂向振動Matlab建模與仿真,基于matlab/simulink的車輛建模與故障分析

隨著鐵路行業高速發展,列車運行速度逐漸提高,鐵路安全越來越受到人們的重視,如何保證鐵道車輛運行安全及其故障監測成為一個亟待解決的重大課題。客車車輛在結構上的故障主要有一系彈簧斷裂、減振器失效、空氣彈簧漏氣、高圓彈簧斷裂、車輪踏面擦傷、軸承故障以及蛇形減震器故障…

關于php的問題有哪些,關于PHP的報錯問題?

關于這個報錯的表格我不知到怎么去做&#xff0c;下面的是代碼&#xff1a;header(content-type:text/html;charsetutf-8);session_start();include_once ../include/conf.php;include_once ../include/func.php;include_once ../include/mysql.func.php;check_login();$pageSi…

oracle消耗內存的查詢,在AIX中計算ORACLE消耗的私有內存總數

一早就收到兄弟伙發的QQ信息&#xff0c;關于aix中oracle內存計算的內容The RSS number is equal to the sum of the number of working-segment pages in memory times 4 andthe code-segment pages in memory times 4.The TRS number is equal to just the code-segment page…

php讀取ds18b20,DS18B20_單總線協議

.H文件#ifndef _ONEWIRE_H#define _ONEWIRE_H#include "STC15F2K60S2.H"#include #define OW_SKIP_ROM 0xcc#define DS18B20_CONVERT 0x44#define DS18B20_READ 0xbe//IC引腳定義sbit DQ P1^4;//函數聲明extern void Delay_OneWire(unsigned int t);extern void Wri…

oracle官方文檔查看方法,oracle官方文檔_查看初始化參數(舉例)

深藍的blog&#xff1a;http://blog.csdn.net/huangyanlong/article/details/46864217記錄了一下&#xff0c;使用oracle11g聯機文檔&#xff0c;查看初始化參數的步驟。如果想查看&#xff0c;可以修改的初始化參數的概念信息&#xff0c;可以點擊“ChangingParameter Values …

matlab usewhitebg,Matlab的:geo??show的網格和框架

對於問題1和問題2&#xff0c;原因是軸總是在圖的後面。因此&#xff0c;一種解決方案是在當前的軸上添加新軸並顯示網格&#xff0c;框和自定義刻度。對於問題3&#xff0c;我使用regexprep以取代S後綴負緯度(同上爲經度)。我唯一的問題是經度0將是0E&#xff0c;緯度0,0N。這…

oracle p l,使用P.A.L制作便攜軟件 (一) 基本原理 | 么么噠擁有者

因愛好自學所得&#xff0c;并非專業&#xff0c;此處只是拋磚引玉&#xff0c;歡迎相互交流、學習、提高&#xff0c;辛苦碼字不易&#xff0c;如轉載望保留鏈接出處。簡單介紹&#xff1a;P.A.L是PortableApps.com Launcher的簡稱&#xff0c;它是PortableApps.com開發的便攜…

oracle form執行后左上角沒出現oracle標記,oracle form學習筆記

新增form步驟打開模板TEMPLATE&#xff0c;將其改成自己所要的名稱&#xff0c;刪除Data Blacks中的BLOCKNAME,DETAILBLOCK,刪除Canvases中的BLOCKNAME,刪除Windows中的BLOCKNAME,新增自己的Windows&#xff0c;Canvases&#xff0c;DateBlacks&#xff0c;在form級別的PRE-FOR…

linux 建oracle分區表,Oracle 10g 11g分區表創建舉例

1.3. 創建其他類型分區表1.3.1. 用多列分區鍵創建范圍分區表SQL> create table aning_mutilcol_range2 (aning_id number,3 aning_name varchar2(100),4 aning_year number,5 aning_month number,6 aning_day number,7 aning_amount number8 )9 partition by range (aning_y…

php carbon 連續日期,日期及時間處理包 Carbon 在 Laravel 中的簡單使用

在編寫 PHP 應用時經常需要處理日期和時間&#xff0c;這篇文章帶你了解一下 Carbon – 繼承自 PHP DateTime 類的 API 擴展&#xff0c;它使得處理日期和時間更加簡單。Laravel 中默認使用的時間處理類就是 Carbon。namespace Carbon;class Carbon extends \DateTime{// code …

chmod g s oracle,chmod

chmod(1)名稱chmod - 更改文件的權限模式用法概要chmod [-fR] absolute-mode file...chmod [-fR] symbolic-mode-list file...chmod [-fR] acl_operation file...chmod [-fR] [- named_attribute]...attribute_specification_list file...描述chmod 實用程序可更改或分配文件的…

linux lzo 壓縮文件,Linux常用壓縮和解壓命令

.tar 解包 tar xvf filename.tar.tar 打包 tar cvf filename.tar dirname.gz 解壓1 gunzip filename.gz.gz 解壓2 gzip -d filename.gz.gz 壓縮 gzip filename.tar.gz 和 .tgz 解壓 tar zxvf filename.tar.gz.tar.gz 和 .tgz 壓縮 tar zcvf filename.tar.gz dirname.bz2 解壓1 …

linux進程cpu時間片,能講一下在Linux系統中時間片是怎么分配的還有優先級的具體算法是...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓圖 1 RT-Linux結構RT -Linux的關鍵技術是通過軟件來模擬硬件的中斷控制器。當Linux系統要封鎖CPU的中斷時時&#xff0c;RT-Linux中的實時子系統會截取到這個請求&#xff0c;把它記錄下來&#xff0c;而實際上并不真正封鎖硬件中斷…