group by的一些優化方案

2022-09-19 09:15:11 字數 2729 閱讀 3529

從哪些方向去優化呢?

我們一起來想下,執行group by語句為什麼需要臨時表呢?group by的語義邏輯,就是統計不同的值出現的個數。如果這個這些值一開始就是有序的,我們是不是直接往下掃瞄統計就好了,就不用臨時表來記錄並統計結果啦?

如何保證group by後面的字段數值一開始就是有序的呢?當然就是加索引啦。

我們回到一下這個sql

select city ,count(*) as num from staff where age= 19 group by city;

複製**

它的執行計畫

如果我們給它加個聯合索引idx_age_city(age,city)

alter table staff add index idx_age_city(age,city);

複製**

再去看執行計畫,發現既不用排序,也不需要臨時表啦。

加合適的索引是優化group by最簡單有效的優化方式。

並不是所有場景都適合加索引的,如果碰上不適合建立索引的場景,我們如何優化呢?

如果你的需求並不需要對結果集進行排序,可以使用order by null

select city ,count(*) as num from staff group by city order by null

複製**

執行計畫如下,已經沒有filesort

如果group by需要統計的資料不多,我們可以盡量只使用記憶體臨時表;因為如果group by 的過程因為資料放不下,導致用到磁碟臨時表的話,是比較耗時的。因此可以適當調大tmp_table_size引數,來避免用到磁碟臨時表

如果資料量實在太大怎麼辦呢?總不能無限調大tmp_table_size吧?但也不能眼睜睜看著資料先放到記憶體臨時表,隨著資料插入發現到達上限,再轉成磁碟臨時表吧?這樣就有點不智慧型啦。

因此,如果預估資料量比較大,我們使用sql_big_result這個提示直接用磁碟臨時表。mysql優化器發現,磁碟臨時表是b+樹儲存,儲存效率不如陣列來得高。因此會直接用陣列來存

示例sql如下:

select sql_big_result city ,count(*) as num from staff group by city;

複製**

執行計畫的extra字段可以看到,執行沒有再使用臨時表,而是只有排序

執行流程如下:

初始化 sort_buffer,放入city欄位;

掃瞄表staff,依次取出city的值,存入 sort_buffer 中;

掃瞄完成後,對 sort_buffer的city欄位做排序

排序完成後,就得到了乙個有序陣列。

根據有序陣列,統計每個值出現的次數。

表結構如下:

create table `staff` (

`id` bigint(11) not null auto_increment comment '主鍵id',

`id_card` varchar(20) not null comment '身份證號碼',

`name` varchar(64) not null comment '姓名',

`status` varchar(64) not null comment 'y-已啟用 i-初始化 d-已刪除 r-審核中',

`age` int(4) not null comment '年齡',

`city` varchar(64) not null comment '城市',

`enterprise_no` varchar(64) not null comment '企業號',

`legal_cert_no` varchar(64) not null comment '法人號碼',

primary key (`id`)

) engine=innodb auto_increment=15 default charset=utf8 comment='員工表';

複製**

查詢的sql是這樣的:

select * from t1 where status = # group by #

一些優化方案

今天和大牛聊天,又討教了一下優化方案。接下來會具體實施。1.場景貼圖合併 規範 2.特效貼圖合併 不採用alpha通道 直接用rgb就可以 用etc壓縮 3.shader.warmupallshaders 預處理shader 4.場景部分物體可以採用lod處理 兩級 看得見 看不見 5.攝像機裁剪處...

mysql 的group by 臨時表一些總結

記憶體表使用場景 1.union執行流程 2.group by 執行流程 3.order by rand 用到二維表的特性需要用到內部臨時表,比如 distinct group by.記憶體臨時表使用memory引擎建立,不同於innodb引擎,order by rand 使用了記憶體臨時表,記憶體...

優化的一些例項

優化使用的工具,使用loadrunner做為壓力測試工具,使用jprobe進行 剖析。1 第乙個例項。原狀況 呼叫乙個api,發現執行的時間很高,用jprobe分析,發現消耗時間最長的是把快取中的乙個樹從第三個節點進行扁平化,就是把第二個節點的子樹構造為乙個列表,不知道為什麼構造這個資料的耗時比直接...