在高併發、大數據量場景(如 P2P 節點管理),查詢與寫入效能至關重要。以下三個經實測有效的優化方向,適用於 MySQL 5.x/8.x。
預處理將 SQL 解析、優化、生成執行計劃的過程前置,重複執行時省去解析開銷,適合「SQL 固定、參數變化、高頻執行」的場景。
MYSQL_STMT *stmt = mysql_stmt_init(mysql);mysql_stmt_prepare(stmt, "INSERT INTO t(a,b,c) VALUES(?,?,?)", len);MYSQL_BIND 陣列,指定型別、緩衝區、長度、is_null。MYSQL_BIND 接收欄位。mysql_stmt_execute(stmt) / mysql_stmt_fetch(stmt)。mysql_stmt_close(stmt);// 1. 準備
char *sql = "INSERT INTO HostCache(SessionID, ChannelID, ISPType, ExternalIP, ExternalPort, InternalIP, InternalPort) VALUES(?,?,?,?,?,?,?)";
mysql_stmt_prepare(stmt, sql, strlen(sql));
// 2. 綁定參數
MYSQL_BIND bind[7];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = (char *)param->sessionid;
bind[0].buffer_length = ID_LENGTH;
bind[0].is_null = 0;
bind[0].length = 0;
// ... bind[1]~bind[6] 同理對應各欄位
mysql_stmt_bind_param(stmt, bind);
// 3. 執行(每次只需填充 param 結構體再呼叫)
strcpy(param->sessionid, sessionid);
// ... 填充其他欄位
mysql_stmt_execute(stmt);
SELECT 欄位全在索引中,避免回表。WHERE DATE(create_time) = '2024-01-01' 會導致索引失效,改用範圍查詢。ANALYZE TABLE:更新統計資訊,幫助優化器做正確決策。傳統 LIMIT 100000, 20 需掃描前 10 萬行,極慢。改用「延遲關聯」或「游標分頁」:
SELECT t.* FROM `table` t
INNER JOIN (
SELECT id FROM `table` WHERE condition ORDER BY id LIMIT 100000, 20
) tmp USING (id);
子查詢只掃描主鍵索引,再回表取完整欄位。
-- 第一頁
SELECT * FROM `table` WHERE condition ORDER BY id LIMIT 20;
-- 後續頁(記住上一頁最後一筆 id)
SELECT * FROM `table` WHERE condition AND id > 12345 ORDER BY id LIMIT 20;
適用於「不需跳頁、只需下一頁」的無限滾動場景,效能極佳。
slow_query_log,設定 long_query_time = 1。EXPLAIN 分析執行計劃,關注 type、key、rows、Extra。