首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP mysqli 預處理編譯深度理解與性能優化

     編輯:MySQL 資料庫相關知識

為什麼需要預編譯?

場景:插入 1000 個用戶。
方案 A:for 循環拼接 SQL → MySQL 重複編譯 1000 次相同語句結構。
方案 B:mysqli_multi_query 拼接 1000 條 → 單次發送大包,但解析優化仍重複。
方案 C:預處理 → prepare 一次 → 循環 bind_param + execute,MySQL 僅編譯優化一次。

完整代碼範例

<?php
$mysqli = new mysqli("localhost", "root", "", "test");
mysqli_query($mysqli, "SET NAMES utf8");

$stmt = $mysqli->prepare("SELECT id, username FROM `user` WHERE `id` > ?");

$id = 5;
$stmt->bind_param("i", $id);      // 綁定輸入參數
$stmt->bind_result($id, $username); // 綁定輸出列
$stmt->execute();

while ($stmt->fetch()) {
    echo "第 {$id} 個用戶: {$username}<br/>";
}

/* 此處可重複修改 $id → bind_param → execute
   無需再次 prepare,複用編譯計劃 */

$stmt->free_result();
$stmt->close();
$mysqli->close();
?>

核心優勢總結

維度普通查詢預處理
編譯次數N 次 (N=執行次數)1 次
網絡傳輸每次發送完整 SQL首次發送模板,後續僅發參數
SQL 注入需手動轉義參數綁定天然免疫
類型安全無bind_param 強類型檢查

進階:事務中批量預處理

$mysqli->begin_transaction();
$stmt = $mysqli->prepare("INSERT INTO log(msg) VALUES(?)");
$stmt->bind_param("s", $msg);

foreach ($messages as $msg) {
    $stmt->execute();
}
$mysqli->commit();
$stmt->close();

避坑指南

  • 預處理不支援某些 SQL(如 CHECK TABLE、部分 DDL)
  • bind_param 參數必須是變量引用,不能直接傳值/表達式
  • 大批量時注意 max_allowed_packet 限制
  • 及時 free_result() 避免內存洩漏
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved