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

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
- PK 是一種唯一索引,確保表中每一行具有唯一識別
- 一個 Table 只能有一個 PK
- PK 不允許包含 NULL 值
- PK 的效能通常非常高,因為 DB 會最佳化主鍵索引的儲存和查找
Unique Index
- 確保表中某一列或多列的組合值是唯一的
- 與 PK 不同,唯一索引允許有多個
- 可防止插入重複數據,保證數據完整性
- 可以包含 NULL 值,但每個 NULL 值在唯一索引中都被視為不同的值
Regular Index
- 也稱為非唯一索引
- 可提高查詢效能,但不對資料的唯一性施加約束
- 允許在同一列中有重複的值
- 在大多數情況下是 B+Tree 索引
Composite Index
- 在多個欄位上建立的索引
- 可在涉及多個列的查詢中提高效能
- 順序很重要,決定如何使用索引進行查詢
- 優化器可使用組合索引的一部分(從左到右),但不能跳過任何列
Full-Text Index
- 主要用於對大量文字資料進行搜尋
- 允許使用自然語言查詢來搜尋文字數據(如查找包含某個字詞或短語的所有記錄)
Covering Index
查詢所需的所有欄位都包含在 Covering Index 中,查詢可以僅使用索引來滿足請求,無需存取實際的表資料,可大大提高查詢效能。在查詢最佳化過程中,充分利用覆蓋索引可避免不必要的 I/O 操作。
Spatial Index
- 用於處理地理空間資料
- 允許在地理空間資料類型(如點、線和多邊形)之間進行查詢和比較
Index Pros & Cons
Pros
- 大大減少伺服器需要掃描的資料行數
- 幫助 Server 避免排序和分組,不需建立 Temporary Table(B+Tree 索引是有序的,可用於
ORDER BY和GROUP BY) - 將隨機 I/O 變成順序 I/O(B+Tree 索引將相鄰的資料儲存在一起)
Cons
- 索引需要額外的儲存空間
UPDATE、INSERT、DELETE操作時,索引也需要維護,導致效能損失- 對於小 Table,全表掃描可能比使用 Index 更快
- 選擇性差的欄位不適用:如果欄位的值分佈均勻,使用 Index 效果不佳
Use Cases
- 非常小的表:簡單的全表掃描更有效率
- 中到大型的表:索引非常有效
- 特大型的表:建立和維護索引的代價隨之成長,需要使用分區技術(Partition)
Index Invalid
以下情況會導致索引失效:
!=或<>會導致索引失效,變成全表掃描- 類型不一致:如欄位是
varchar,但查詢時使用int(隱式類型轉換) - 對索引欄位使用
count、sum等函數操作 - 模糊搜尋時,字串前綴也是模糊的(
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_ci | Unicode 標準通用排序 | 是 | 是 | 通用,多語言適用 |
| utf8mb4_general_ci | 通用排序,較快但排序準確度較低 | 是 | 是 | 通用 |
| utf8mb4_bin | 依字節序排序 | 否 | 否 | 嚴格比較 |
| utf8mb4_unicode_520_ci | Unicode 5.2.0 標準排序 | 是 | 是 | 通用,多語言適用 |
| utf8mb4_0900_ai_ci | MySQL 8.0+ 基於 Unicode 9.0 | 是 | 是 | 通用,多語言適用 |
| utf8mb4_0900_as_cs | MySQL 8.0+ 基於 Unicode 9.0 | 否 | 否 | 通用,多語言適用 |