MySQL 內建一個鮮為人知的 HANDLER 命令,繞過 SQL 解析器與優化器,直接存取儲存引擎介面。實測主鍵查詢效能較標準 SQL 提升 40%-45%,24 核伺服器單表主鍵查詢可達 37 萬 QPS。但為何生產環境鮮見使用?本文深度剖析。
HANDLER tbl_name OPEN [ [AS] alias ]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...) [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE
測試腳本:
SET @id = FLOOR(RAND()*1000000);
HANDLER sbtest.sbtest1 OPEN AS c;
HANDLER c READ `PRIMARY` = (@id);
HANDLER c CLOSE;
64 線程壓測結果:
Sql_cmd_handler_open::executeSql_cmd_handler_read::executeSql_cmd_handler_close::executeha_innobase::init_table_handle_for_HANDLERha_partition::init_table_handle_for_HANDLER (5.7+ 支援分區表)官方文件稱「允許髒讀」,但 InnoDB 實際實現**支援一致性讀取**:
/* We let HANDLER always to do the reads as consistent reads, even
if the trx isolation level would have been specified as SERIALIZABLE */
m_prebuilt->select_lock_type = LOCK_NONE;
m_prebuilt->stored_select_lock_type = LOCK_NONE;
源碼註釋明確:HANDLER 總是以一致性讀執行,分配 ReadView,親測無髒讀問題。
| 限制 | 影響 |
|---|---|
| 僅支援單表,無 JOIN | 無法處理關聯查詢 |
| 二級索引讀取仍回傳全行(所有欄位) | 無法投影特定欄位,網路/IO 浪費 |
| 二級索引不支援 LIMIT | 只能回傳 1 筆記錄 |
| 不支援 DML(INSERT/UPDATE/DELETE) | 唯讀場景受限 |