mysql資料庫對group(mysql資料庫對比工具)

本文目錄一覽:

mysql資料庫 group by 報錯 原理是什麼?

在日常查詢中,索引或其他數據查找的方法可能不是查詢執行中最高昂的部分,例如:MySQL GROUP BY 可能負責查詢執行時間 90% 還多。MySQL 執行 GROUP BY 時的主要複雜性是計算 GROUP BY 語句中的聚合函數。UDF 聚合函數是一個接一個地獲得構成單個組的所有值。這樣,它可以在移動到另一個組之前計算單個組的聚合函數值。當然,問題在於,在大多數情況下,源數據值不會被分組。來自各種組的值在處理期間彼此跟隨。因此,我們需要一個特殊的步驟。

處理 MySQL GROUP BY讓我們看看之前看過的同一張table:    mysql show create table tbl G    *************************** 1. row ***************************          Table: tbl    Create Table: CREATE TABLE `tbl` (     `id` int(11) NOT NULL AUTO_INCREMENT,     `k` int(11) NOT NULL DEFAULT ‘0’,     `g` int(10) unsigned NOT NULL,     PRIMARY KEY (`id`),     KEY `k` (`k`)    ) ENGINE=InnoDB AUTO_INCREMENT=2340933 DEFAULT CHARSET=latin1    1 row in set (0.00 sec)

並且以不同方式執行相同的 GROUP BY 語句:

1、MySQL中 的 Index Ordered GROUP BY

mysql select k, count(*) c from tbl group by k order by k limit 5;

+—+—+

| k | c |

+—+—+

| 2 | 3 |

| 4 | 1 |

| 5 | 2 |

| 8 | 1 |

| 9 | 1 |

+—+—+

5 rows in set (0.00 sec)

mysql explain select k, count(*) c from tbl group by k order by k limit 5 G

*************************** 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: Using index

1 row in set, 1 warning (0.00 sec)

在這種情況下,我們在 GROUP BY 的列上有一個索引。這樣,我們可以逐組掃描數據並動態執行 GROUP BY(低成本)。當我們使用 LIMIT 限制我們檢索的組的數量或使用「覆蓋索引」時,特別有效,因為順序索引掃描是一種非常快速的操作。

如果您有少量組,並且沒有覆蓋索引,索引順序掃描可能會導致大量 IO。所以這可能不是最優化的計劃。

2、MySQL 中的外部排序 GROUP BY

mysql explain select SQL_BIG_RESULT g, count(*) c from tbl group by g limit 5 G

*************************** 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: Using filesort

1 row in set, 1 warning (0.00 sec)

mysql select SQL_BIG_RESULT g, count(*) c from tbl group by g limit 5;

+—+—+

| g | c |

+—+—+

| 0 | 1 |

| 1 | 2 |

| 4 | 1 |

| 5 | 1 |

| 6 | 2 |

+—+—+

5 rows in set (0.88 sec)

如果我們沒有允許我們按組順序掃描數據的索引,我們可以通過外部排序(在 MySQL 中也稱為「filesort」)來獲取數據。你可能會注意到我在這裡使用 SQL_BIG_RESULT 提示來獲得這個計劃。沒有它,MySQL 在這種情況下不會選擇這個計劃。

一般來說,MySQL 只有在我們擁有大量組時才更喜歡使用這個計劃,因為在這種情況下,排序比擁有臨時表更有效(我們將在下面討論)。

3、MySQL中 的臨時表 GROUP BY

mysql explain select  g, sum(g) s from tbl group by g limit 5 G

*************************** 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: Using temporary

1 row in set, 1 warning (0.00 sec)

mysql select  g, sum(g) s from tbl group by g order by null limit 5;

+—+——+

| g | s    |

+—+——+

| 0 |    0 |

| 1 |    2 |

| 4 |    4 |

| 5 |    5 |

| 6 |   12 |

+—+——+

5 rows in set (7.75 sec)

在這種情況下,MySQL 也會進行全表掃描。但它不是運行額外的排序傳遞,而是創建一個臨時表。此臨時表每組包含一行,並且對於每個傳入行,將更新相應組的值。很多更新!雖然這在內存中可能是合理的,但如果結果表太大以至於更新將導致大量磁碟 IO,則會變得非常昂貴。在這種情況下,外部分揀計劃通常更好。請注意,雖然 MySQL 默認選擇此計劃用於此用例,但如果我們不提供任何提示,它幾乎比我們使用 SQL_BIG_RESULT 提示的計劃慢 10 倍 。您可能會注意到我在此查詢中添加了「 ORDER BY NULL 」。這是為了向您展示「清理」臨時表的唯一計劃。沒有它,我們得到這個計劃:    mysql explain select  g, sum(g) s from tbl group by g limit 5 G    *************************** 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: Using temporary; Using filesort    1 row in set, 1 warning (0.00 sec)

在其中,我們獲得了 temporary 和 filesort 「兩最糟糕的」提示。MySQL 5.7 總是返回按組順序排序的 GROUP BY 結果,即使查詢不需要它(這可能需要昂貴的額外排序傳遞)。ORDER BY NULL 表示應用程序不需要這個。您應該注意,在某些情況下 – 例如使用聚合函數訪問不同表中的列的 JOIN 查詢 – 使用 GROUP BY 的臨時表可能是唯一的選擇。

如果要強制 MySQL 使用為 GROUP BY 執行臨時表的計劃,可以使用 SQL_SMALL_RESULT 提示。

4、MySQL 中的索引基於跳過掃描的 GROUP BY前三個 GROUP BY 執行方法適用於所有聚合函數。然而,其中一些人有第四種方法。

mysql explain select k,max(id) from tbl group by k G

*************************** 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: Using index for group-by

1 row in set, 1 warning (0.00 sec)

mysql select k,max(id) from tbl group by k;

+—+———+

| k | max(id) |

+—+———+

| 0 | 2340920 |

| 1 | 2340916 |

| 2 | 2340932 |

| 3 | 2340928 |

| 4 | 2340924 |

+—+———+

5 rows in set (0.00 sec)

此方法僅適用於非常特殊的聚合函數:MIN() 和 MAX()。這些並不需要遍歷組中的所有行來計算值。他們可以直接跳轉到組中的最小或最大組值(如果有這樣的索引)。如果索引僅建立在 (K) 列上,如何找到每個組的 MAX(ID) 值?這是一個 InnoDB 表。記住 InnoDB 表有效地將 PRIMARY KEY 附加到所有索引。(K) 變為 (K,ID),允許我們對此查詢使用 Skip-Scan 優化。僅當每個組有大量行時才會啟用此優化。否則,MySQL 更傾向於使用更傳統的方法來執行此查詢(如方法#1中詳述的索引有序 GROUP BY)。雖然我們使用 MIN() / MAX() 聚合函數,但其他優化也適用於它們。例如,如果您有一個沒有 GROUP BY 的聚合函數(實際上所有表都有一個組),MySQL 在統計分析階段從索引中獲取這些值,並避免在執行階段完全讀取表:    mysql explain select max(k) from tbl G    *************************** 1. row ***************************              id: 1     select_type: SIMPLE           table: NULL      partitions: NULL            type: NULL    possible_keys: NULL             key: NULL         key_len: NULL             ref: NULL            rows: NULL        filtered: NULL           Extra: Select tables optimized away    1 row in set, 1 warning (0.00 sec)

過濾和分組

我們已經研究了 MySQL 執行 GROUP BY 的四種方式。為簡單起見,我在整個表上使用了 GROUP BY,沒有應用過濾。當您有 WHERE 子句時,相同的概念適用:    mysql explain select  g, sum(g) s from tbl where k4 group by g order by NULL limit 5 G    *************************** 1. row ***************************              id: 1     select_type: SIMPLE           table: tbl      partitions: NULL            type: range    possible_keys: k             key: k         key_len: 4             ref: NULL            rows: 1        filtered: 100.00           Extra: Using index condition; Using temporary    1 row in set, 1 warning (0.00 sec)

對於這種情況,我們使用K列上的範圍進行數據過濾/查找,並在有臨時表時執行 GROUP BY。在某些情況下,方法不會發生衝突。但是,在其他情況下,我們必須選擇使用 GROUP BY 的一個索引或其他索引進行過濾:

mysql alter table tbl add key(g);

Query OK, 0 rows affected (4.17 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql explain select  g, sum(g) s from tbl where k1 group by g limit 5 G

*************************** 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: Using where

1 row in set, 1 warning (0.00 sec)

mysql explain select  g, sum(g) s from tbl where k4 group by g limit 5 G

*************************** 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: Using index condition; Using temporary; Using filesort

1 row in set, 1 warning (0.00 sec)

根據此查詢中使用的特定常量,我們可以看到我們對 GROUP BY 使用索引順序掃描(並從索引中「放棄」以解析 WHERE 子句),或者使用索引來解析 WHERE 子句(但使用臨時表來解析 GROUP BY)。根據我的經驗,這就是 MySQL GROUP BY 並不總是做出正確選擇的地方。您可能需要使用 FORCE INDEX 以您希望的方式執行查詢。

如何對mysql的group

例子 aa表 a b

123 10

123 12

1234 11

1234 14

首先 group 是用來分組的 不是過濾重複項的。重複項刪除語句 DISTINCT用這個 。 select DISTINCT(a) from aa

結果就是 a

123

1234

group by用來分組的

select a, sum(b) from aa group by a

sum意思是總和。結果就是

a b

123 22

1234 25

語句的目的是以a為目標 需要知道 相同名字的物品 在b列一共有多少數量總和

select a,count(b) from aa group by a

count 意思行數總和 結果就是

a b

123 2

1234 2

語句目的是 相同名字的物品 一共有幾行

如何理解mysql中GROUP

就是給數據分類匯總,比如group by name,就是按name分類,相同名字的數據都匯總到這個名字中

MySql操作「數據查詢」-20211222

# SELECT 數據查詢

## 基礎

顯示如何使用簡單的`select`語句查詢單個表中的數據 使用`SELECT`語句從表或視圖獲取數據。

表由行和列組成,如電子表格。 通常,我們只希望看到子集行,列的子集或兩者的組合。

SELECT語句的結果稱為結果集,它是行列表,每行由相同數量的列組成。

select 語法

SELECT語句由以下列表中所述的幾個子句組成:

1. SELECT 之後是逗號分隔列或星號(*)的列表,表示要返回所有列。

2. FROM 指定要查詢數據的表或視圖。

3. JOIN 根據某些連接條件從其他表中獲取數據。

4. WHER E過濾結果集中的行。

5. GROUP BY將一組行組合成小分組,並對每個小分組應用聚合函數。

6. HAVING 過濾器基於GROUP BY子句定義的小分組。

7. ORDER BY 指定用於排序的列的列表。

8. LIMIT 限制返回行的數量。

語句中的`SELECT`和`FROM`語句是必須的,其他部分是可選的。

`SELECT`語句允許通過在`SELECT`子句中指定逗號分隔列的列表來查詢表的部分數據

建議顯式獲取數據的列,原因如下:

1. 使用星號(*)可能會返回不使用的列的數據。 它在MySQL資料庫伺服器和應用程序之間產生不必要的I/O磁碟和網路流量。

2. 如果明確指定列,則結果集更可預測並且更易於管理。 想像一下,當您使用星號(*)並且有人通過添加更多列來更改表格數據時,將會得到一個與預期不同的結果集。

3. 使用星號(*)可能會將敏感信息暴露給未經授權的用戶

格式 `select 列篩選 form table where 行篩選`

還有一些有用的運算符可以在WHERE子句中使用來形成複雜的條件,例如:

BETWEEN 選擇在給定範圍之內的值。

LIKE 匹配基於模式匹配的值。

IN 指定值是否匹配列表中的任何值。

IS NULL 檢查該值是否為NULL。

## SELECT 子查詢

在一個查詢過程中 嵌套另一個查詢,子查詢的結果作為外部查詢的條件或者數據範圍來使用。

分為 3 類:

1. where 型

– `select展示列名 from 表名 where 列名 運算符[in…] (select 對應列名 from …)`

– 這個列名 和 對應列名 應該做到類型相同

– 如果不加入運算符 也可使用IN 這些類似的符號 – `select 展示列名 from 表名 where 列名 in (select 對應列名 from …)`

– ex:

`select 展示列名 from 表名 where 列名 ALL(select 對應列名 from ….)`;

比子查詢的值都大

`select 展示列名 from 表名 where 列名 ANY(select 對應列名 from ….);`

比子查詢的任意一個值大

2. from 型

– `select 展示列名 from 表名 inner join (select 列名 from …) 臨時表名 on 條件;`

– 其中,select的子查詢所得的表 為臨時表,後跟臨時表名,可在條件判斷中指代

3. exist 型

– `select 展示列 from 表名 where exists (select 列名 from 表名 where 條件);`

– 將主查詢的結果帶入子查詢進行條件判斷和匹配,如果查詢出結果即保留。

## 去重 DISTINCT

SELECT 語句執行簡單的數據查詢時,返回的是所有匹配的記錄。`distinct` 實現查詢不重複的數據

**DISTINCT 關鍵字的主要作用就是對數據表中一個或多個欄位重複的數據進行過濾,只返回其中的一條數據給用戶。**

使用 `DISTINCT` 關鍵字時需要注意以下幾點:

– `DISTINCT` 關鍵字只能在 `SELECT` 語句中使用。

– 在對一個或多個欄位去重時,`DISTINCT` 關鍵字必須在所有欄位的最前面。

– 如果 `DISTINCT` 關鍵字後有多個欄位,則會對多個欄位進行組合去重,也就是說,只有多個欄位組合起來完全是一樣的情況下才會被去重。

## 指定別名 AS

### 1. 為表指定別名

1. 當表名很長的時候 或者 執行了一些特殊的查詢的時候,為方便操作,可以為表指定一個別名,用以替代原來的名稱

2. 語法.

3. `表名 as 別名` – 含義: – `表名` : 資料庫中存儲的數據表名稱。

– `別名` : 查詢的時候指定的新的名稱。

– `as` : 此關鍵字 可以 省略,省略之後要將 `表名`與`別名`用 `空格` 分開

** *注意:表的別名不能與該資料庫的其它表同名。欄位的別名不能與該表的其它欄位同名。在條件表達式中不能使用欄位的別名,否則會出現「ERROR 1054 (42S22): Unknown column」這樣的錯誤提示信息。* **

*** ex1:

***

### 2. 為欄位指定別名

1. 在使用 SELECT 語句查詢數據時,MySQL 會顯示每個 SELECT 後面指定輸出的欄位。有時為了顯示結果更加直觀,我們可以為欄位指定一個別名。

2. 語法:

3. `欄位名 [AS] 別名`

– 含義:

– `欄位名`:為數據表中欄位定義的名稱。

– `欄位別名`:欄位新的名稱。

– `AS` 關鍵字可以省略,省略後需要將欄位名和別名用空格隔開

** *注意:表別名只在執行查詢時使用,並不在返回結果中顯示。而欄位定義別名之後,會返回給客戶端顯示,顯示的欄位為欄位的別名* ** ***

ex2:

***

## 限制查詢條數 LIMIT

1. LIMIT 關鍵字有 3 種使用方式,即

– `指定初始位置`、

– `不指定初始位置`

– `OFFSET 組合`使用

(。。。。。 我之前一直不知道, 只會使用 `limit 200`。。。。。)

### 指定初始位置

1. 語法

– `LIMIT 初始位置,記錄數`

– 初始位置」表示從哪條記錄開始顯示;第一條記錄的位置是 0,第二條記錄的位置是 1。後面的記錄依次類推。

– 「記錄數」表示顯示記錄的條數。

– *LIMIT 後的兩個參數必須都是正整數。

* ex:tb_students_info 表中,使用 LIMIT 子句返回從第 4 條記錄開始的行數為 5 的記錄,SQL 語句和運行結果如下。

### 不指定初始位置

記錄從第一條記錄開始顯示。顯示記錄的條數由 LIMIT 關鍵字指定。

1. 語法

– `LIMIT 5`

– `SELECT * FROM tb_students_info LIMIT 15;`

### LIMIT 和 OFFSET 組合使用

1. 語法

– `LIMIT 記錄數 OFFSET 初始位置`

– 參數和 LIMIT 語法中參數含義相同,「初始位置」指定從哪條記錄開始顯示;「記錄數」表示顯示記錄的條數。

該語句返回的是從第 4 條記錄開始的之後的 5 條記錄。即「 LIMIT 5 OFFSET 3 」意思是獲取從第 4 條記錄開始的後面的 5 條記錄,和「 LIMIT 3 , 5 」返回的結果相同。

*** 2021-12-22 今天先學到這裡 明天繼續 MySql 的查詢 學習

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/257555.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-15 12:44
下一篇 2024-12-15 12:44

相關推薦

  • 如何修改mysql的埠號

    本文將介紹如何修改mysql的埠號,方便開發者根據實際需求配置對應埠號。 一、為什麼需要修改mysql埠號 默認情況下,mysql使用的埠號是3306。在某些情況下,我們需…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • Python 常用資料庫有哪些?

    在Python編程中,資料庫是不可或缺的一部分。隨著互聯網應用的不斷擴大,處理海量數據已成為一種趨勢。Python有許多成熟的資料庫管理系統,接下來我們將從多個方面介紹Python…

    編程 2025-04-29
  • openeuler安裝資料庫方案

    本文將介紹在openeuler操作系統中安裝資料庫的方案,並提供代碼示例。 一、安裝MariaDB 下面介紹如何在openeuler中安裝MariaDB。 1、更新軟體源 sudo…

    編程 2025-04-29
  • Python操作MySQL

    本文將從以下幾個方面對Python操作MySQL進行詳細闡述: 一、連接MySQL資料庫 在使用Python操作MySQL之前,我們需要先連接MySQL資料庫。在Python中,我…

    編程 2025-04-29
  • 如何通過jstack工具列出假死的java進程

    假死的java進程是指在運行過程中出現了某些問題導致進程停止響應,此時無法通過正常的方式關閉或者重啟該進程。在這種情況下,我們可以藉助jstack工具來獲取該進程的進程號和線程號,…

    編程 2025-04-29
  • 資料庫第三範式會有刪除插入異常

    如果沒有正確設計資料庫,第三範式可能導致刪除和插入異常。以下是詳細解釋: 一、什麼是第三範式和範式理論? 範式理論是關係資料庫中的一個規範化過程。第三範式是範式理論中的一種常見形式…

    編程 2025-04-29
  • 註冊表取證工具有哪些

    註冊表取證是數字取證的重要分支,主要是獲取計算機系統中的註冊表信息,進而分析痕迹,獲取重要證據。本文將以註冊表取證工具為中心,從多個方面進行詳細闡述。 一、註冊表取證工具概述 註冊…

    編程 2025-04-29
  • MySQL遞歸函數的用法

    本文將從多個方面對MySQL遞歸函數的用法做詳細的闡述,包括函數的定義、使用方法、示例及注意事項。 一、遞歸函數的定義 遞歸函數是指在函數內部調用自身的函數。MySQL提供了CRE…

    編程 2025-04-29
  • leveldb和unqlite:兩個高性能的資料庫存儲引擎

    本文將介紹兩款高性能的資料庫存儲引擎:leveldb和unqlite,並從多個方面對它們進行詳細的闡述。 一、leveldb:輕量級的鍵值存儲引擎 1、leveldb概述: lev…

    編程 2025-04-28

發表回復

登錄後才能評論