SQL Glossary

SQL 命令參考手冊,涵蓋 DML/DDL/DCL/TCL 命令、執行順序、索引類型與 MySQL 特性。

SQL Commands

DML (Data Manipulation Language)

資料操作語言,用於查詢和修改資料。

命令說明
SELECT查詢資料
INSERT插入資料
UPDATE更新資料
DELETE刪除資料

DDL (Data Definition Language)

資料定義語言,用於定義資料庫結構。

命令說明
CREATE建立物件(表格、視圖等)
ALTER修改物件結構
DROP刪除物件
COMMENT新增註解
TRUNCATE清空表格資料

DCL (Data Control Language)

資料控制語言,用於管理使用者權限。

命令說明
GRANT授予權限
REVOKE撤銷權限

TCL (Transaction Control Language)

交易控制語言,通常與 DML 操作一起使用。

命令說明
SAVE POINT設定儲存點
ROLL BACK回滾交易
COMMIT提交交易
SET TRANSACTION設定交易特性

Execution Order

SQL 查詢的執行順序:

  flowchart LR
    FROM --> JOIN --> ON --> WHERE --> GROUP_BY --> HAVING --> SELECT --> ORDER_BY --> LIMIT
SQL Execution Order

Query Execution Plans

Query Execution Plans

SARGABLE Query

SARGABLE = Search ARGument ABLE(可以用索引尋找)

SARGABLE Query

WHERE order_date >= '2024-01-01'

Non-SARGABLE Query

此 Query 在比較之前,資料庫需要對每一筆資料的 order_date 執行 YEAR() 函數,可能導致全表掃描或額外的資源消耗。
WHERE YEAR(order_date) >= 2024

撰寫 SARGABLE Query 的原則

  • 避免在 WHERE 子句中對索引欄位使用函數或計算
  • 盡可能使用直接比較,而非將欄位包裝在函數中
  • 如果需要對欄位使用函數,考慮建立 computed column 或 function-based index

Index Structure

B+Tree

MySQL 最常用的索引結構,支援範圍查詢和排序。

Full-Text

全文索引,用於文字搜尋。

Hash

  • Time Complexity: O(1)
  • 無有序性,無法用於排序與分組
  • 只支援精確查找,無法用於部分查找和範圍查找
InnoDB Adaptive Hash Index:當某個索引值被非常頻繁使用時,會在 B+Tree index 之上再創建一個 hash index,讓 B+Tree index 具有 hash index 的一些優點。

R-Tree

  • 空間數據索引
  • 可用於地理資料儲存
  • 從所有維度索引數據,可進行任意維度組合查詢
  • 必須使用 GIS 相關函數來維護資料

Index Types

Primary Key Index

  1. PK 是一種唯一索引,確保表中每一行具有唯一識別
  2. 一個 Table 只能有一個 PK
  3. PK 不允許包含 NULL 值
  4. PK 的效能通常非常高,因為 DB 會最佳化主鍵索引的儲存和查找

Unique Index

  1. 確保表中某一列或多列的組合值是唯一的
  2. 與 PK 不同,唯一索引允許有多個
  3. 可防止插入重複數據,保證數據完整性
  4. 可以包含 NULL 值,但每個 NULL 值在唯一索引中都被視為不同的值

Regular Index

  1. 也稱為非唯一索引
  2. 可提高查詢效能,但不對資料的唯一性施加約束
  3. 允許在同一列中有重複的值
  4. 在大多數情況下是 B+Tree 索引

Composite Index

  1. 在多個欄位上建立的索引
  2. 可在涉及多個列的查詢中提高效能
  3. 順序很重要,決定如何使用索引進行查詢
  4. 優化器可使用組合索引的一部分(從左到右),但不能跳過任何列

Full-Text Index

  1. 主要用於對大量文字資料進行搜尋
  2. 允許使用自然語言查詢來搜尋文字數據(如查找包含某個字詞或短語的所有記錄)

Covering Index

查詢所需的所有欄位都包含在 Covering Index 中,查詢可以僅使用索引來滿足請求,無需存取實際的表資料,可大大提高查詢效能。在查詢最佳化過程中,充分利用覆蓋索引可避免不必要的 I/O 操作。

Spatial Index

  1. 用於處理地理空間資料
  2. 允許在地理空間資料類型(如點、線和多邊形)之間進行查詢和比較

Index Pros & Cons

Pros

  1. 大大減少伺服器需要掃描的資料行數
  2. 幫助 Server 避免排序和分組,不需建立 Temporary Table(B+Tree 索引是有序的,可用於 ORDER BYGROUP BY
  3. 將隨機 I/O 變成順序 I/O(B+Tree 索引將相鄰的資料儲存在一起)

Cons

  1. 索引需要額外的儲存空間
  2. UPDATEINSERTDELETE 操作時,索引也需要維護,導致效能損失
  3. 對於小 Table,全表掃描可能比使用 Index 更快
  4. 選擇性差的欄位不適用:如果欄位的值分佈均勻,使用 Index 效果不佳

Use Cases

  • 非常小的表:簡單的全表掃描更有效率
  • 中到大型的表:索引非常有效
  • 特大型的表:建立和維護索引的代價隨之成長,需要使用分區技術(Partition)

Index Invalid

以下情況會導致索引失效:

  • !=<> 會導致索引失效,變成全表掃描
  • 類型不一致:如欄位是 varchar,但查詢時使用 int(隱式類型轉換)
  • 對索引欄位使用 countsum 等函數操作
  • 模糊搜尋時,字串前綴也是模糊的(LIKE '%xxx'
  • 聯合索引(Compound Indexes)查詢條件不滿足最左匹配原則
  • 在 Compound Indexes 下,使用明確的欄位查詢代替 *,有機會走覆蓋索引

InnoDB

支援索引結構:B+Tree、Hash、Full-Text

Isolation Level

隔離層級是資料庫管理系統中設定交易(Transaction)之間互相隔離程度的配置選項。

隔離層級控制在多個交易並發(concurrent)執行時,數據的一致性和完整性,防止數據競爭和不一致的問題。隔離層級越高,交易之間的干擾越小,但可能影響系統的性能和並發性。

MyISAM

支援索引結構:Full-Text、R-Tree

  • 使用 Inverted index
  • 不支援 Transaction 和 FK
  • 主要用來代替 LIKE '%xxx%' 效率低的問題

MySQL Monitor

連線池監控

-- 查看最大允許連線數
SHOW VARIABLES LIKE 'max_connections';

-- 查看當前已使用的連線數
SHOW STATUS LIKE 'Threads_connected';

-- 查看歷史最大連線數
SHOW STATUS LIKE 'Max_used_connections';

-- 計算連線使用率
SELECT
  ROUND(100 * (A.variable_value / B.variable_value), 2) AS connection_usage_percentage
FROM
  (SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Threads_connected') A,
  (SELECT variable_value FROM performance_schema.global_variables WHERE variable_name = 'max_connections') B;

緩存監控

-- 查看 InnoDB Buffer Pool 設置
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

-- 計算緩存命中率
SELECT
  ROUND(100 * (1 - (A.variable_value / B.variable_value)), 2) AS buffer_pool_hit_ratio
FROM
  (SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_reads') A,
  (SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_read_requests') B;
命中率 > 95%:緩存表現良好 命中率 < 80%:可能需要增加 innodb_buffer_pool_size

查詢效能監控

-- 查看查詢執行計劃
EXPLAIN SELECT * FROM table_name WHERE column_name = 'value';

-- 查看慢查詢日誌是否啟用
SHOW VARIABLES LIKE 'slow_query_log';

-- 查詢執行時間最長的 SQL 語句
SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

磁碟空間監控

-- 查詢所有數據庫的大小
SELECT table_schema AS "Database",
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)"
FROM information_schema.tables
GROUP BY table_schema;

-- 查詢單個表的大小
SELECT table_name AS "Table",
       ROUND((data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)"
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
ORDER BY (data_length + index_length) DESC
LIMIT 10;

事務與鎖監控

-- 查看當前 InnoDB 事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

-- 查看 InnoDB 鎖狀態
SHOW ENGINE INNODB STATUS;

連線管理

-- 手動關閉某個連線
KILL thread_id;

-- 批量關閉超時連線(生成 KILL 命令)
SELECT CONCAT('KILL ',id,';') FROM information_schema.processlist
WHERE command='Sleep' AND time > 300;

ALTER ALGORITHM

適合使用 ALGORITHM=INPLACE

操作類型適用情境說明
新增欄位新增非索引欄位不重建資料表即可增加欄位
修改欄位名稱重新命名欄位結構性修改,不影響基礎結構
刪除欄位刪除非索引欄位資料表結構不會大幅改動
新增索引單一欄位索引快速新增索引,不需重建整個表
刪除索引刪除索引不影響資料表的基礎結構

不適合使用 ALGORITHM=INPLACE

操作類型適用情境說明
修改欄位類型如從 INT 改為 VARCHAR需重新排序資料或重新計算索引,觸發表重建
修改索引結構更改索引的欄位涉及資料表重新排序或重建索引
大型資料表的結構更改需要重建索引或重新排序某些操作需觸發資料表重建

Collate

COLLATE 名稱說明忽略大小寫忽略重音符語言適用性
utf8mb4_unicode_ciUnicode 標準通用排序通用,多語言適用
utf8mb4_general_ci通用排序,較快但排序準確度較低通用
utf8mb4_bin依字節序排序嚴格比較
utf8mb4_unicode_520_ciUnicode 5.2.0 標準排序通用,多語言適用
utf8mb4_0900_ai_ciMySQL 8.0+ 基於 Unicode 9.0通用,多語言適用
utf8mb4_0900_as_csMySQL 8.0+ 基於 Unicode 9.0通用,多語言適用