1. 程式人生 > >MySQL的預編譯功能簡述

MySQL的預編譯功能簡述

預編譯的好處

大家平時都使用過JDBC中的PreparedStatement介面,它有預編譯功能。什麼是預編譯功能呢?它有什麼好處呢?

當客戶傳送一條SQL語句給伺服器後,伺服器總是需要校驗SQL語句的語法格式是否正確,然後把SQL語句編譯成可執行的函式,最後才是執行SQL語句。其中校驗語法,和編譯所花的時間可能比執行SQL語句花的時間還要多。

如果我們需要執行多次insert語句,但只是每次插入的值不同,MySQL伺服器也是需要每次都去校驗SQL語句的語法格式,以及編譯,這就浪費了太多的時間。如果使用預編譯功能,那麼只對SQL語句進行一次語法校驗和編譯,所以效率要高。

MySQL執行預編譯

MySQL執行預編譯分為如三步:

l  執行預編譯語句,例如:prepare myfun from 'select * from t_book where bid=?'

l  設定變數,例如:set @str='b1'

l  執行語句,例如:execute myfun using @str

如果需要再次執行myfun,那麼就不再需要第一步,即不需要再編譯語句了:

l  設定變數,例如:set @str='b2'

l  執行語句,例如:execute myfun using @str

通過檢視MySQL日誌可以看到執行的過程:

使用Statement執行預編譯

使用Statement執行預編譯就是把上面的SQL語句執行一次。

       Connection con = JdbcUtils.getConnection();

       Statement stmt = con.createStatement();

       stmt.executeUpdate("prepare myfun from 'select * from t_book where bid=?'");

       stmt.executeUpdate("set @str='b1'");

       ResultSet rs = stmt.executeQuery("execute myfun using @str");

       while

(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       stmt.executeUpdate("set @str='b2'");

       rs = stmt.executeQuery("execute myfun using @str");

       while(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       rs.close();

       stmt.close();

       con.close();

useServerPrepStmts引數

預設使用PreparedStatement是不能執行預編譯的,這需要在url中給出useServerPrepStmts=true引數(MySQL Server 4.1之前的版本是不支援預編譯的,而Connector/J在5.0.5以後的版本,預設是沒有開啟預編譯功能的)。

例如:jdbc:mysql://localhost:3306/test?useServerPrepStmts=true

  這樣才能保證mysql驅動會先把SQL語句傳送給伺服器進行預編譯,然後在執行executeQuery()時只是把引數傳送給伺服器。

       Connection con = JdbcUtils.getConnection();

       String sql = "select * from t_book where bid=?";

       PreparedStatement pstmt = con.prepareStatement(sql);

       pstmt.setString(1, "b1");

       ResultSet rs = pstmt.executeQuery();

       while(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       pstmt.setString(1, "b2");

       rs = pstmt.executeQuery();

       while(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       rs.close();

       pstmt.close();

       con.close();

cachePrepStmts引數

當使用不同的PreparedStatement物件來執行相同的SQL語句時,還是會出現編譯兩次的現象,這是因為驅動沒有快取編譯後的函式key,導致二次編譯。如果希望快取編譯後函式的key,那麼就要設定cachePrepStmts引數為true。例如:

jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&cachePrepStmts=true

       Connection con = JdbcUtils.getConnection();

       String sql = "select * from t_book where bid=?";

       PreparedStatement pstmt = con.prepareStatement(sql);

       pstmt.setString(1, "b1");

       ResultSet rs = pstmt.executeQuery();

       while(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       pstmt = con.prepareStatement(sql);

       pstmt.setString(1, "b2");

       rs = pstmt.executeQuery();

       while(rs.next()) {

           System.out.print(rs.getString(1) + ", ");

           System.out.print(rs.getString(2) + ", ");

           System.out.print(rs.getString(3) + ", ");

           System.out.println(rs.getString(4));

       }

       rs.close();

       pstmt.close();

       con.close();

開啟批處理

MySQL的批處理也需要通過引數來開啟:rewriteBatchedStatements=true

相關推薦

MySQL編譯功能簡述

預編譯的好處 大家平時都使用過JDBC中的PreparedStatement介面,它有預編譯功能。什麼是預編譯功能呢?它有什麼好處呢? 當客戶傳送一條SQL語句給伺服器後,伺服器總是需要校驗SQL語句的語法格式是否正確,然後把SQL語句編譯成可執行的函式,最後才是執行SQL

MySQL編譯功能

.cn 支持 right amp print div 服務 nec rom 1、預編譯的好處   大家平時都使用過JDBC中的PreparedStatement接口,它有預編譯功能。什麽是預編譯功能呢?它有什麽好處呢?   當客戶發送一條SQL語句給服務器後,服務器總是

誤用Freemarker標籤和SpringJDBC編譯功能導致的記憶體洩露問題分析

一. 問題描述         本人所在的專案組專案已經執行快一年了,功能效能都比較穩定。但是最近釋出了一個版本,只是業務上增加了一些資料量,最終效果卻是在持續執行的過程中,出現OOM異常。之前也發過一些版本,做過一些類似的調整,都沒有出現效能問題,而這個版本卻出現了,著實

使用PreparedStatement 防止SQL攻擊 實現編譯功能提高效能

public boolean login(String username,String password) throws Exception { String driverClassName="com.mysql.jdbc.Driver"; S

探究mysql編譯

本文來源於http://cs-css.iteye.com/blog/1847772, 網上的絕大部分關於預編譯的文章都是簡單介紹預編譯有什麼優缺點、怎麼用,而本文作者通過實踐深入探究了預編譯的開啟條件以及對效能的影響。一.背景:用Mybatis+mysql的架構做開發,大家都

C語言中的三大編譯功能

這三種預處理包括:巨集定義、檔案包含、條件編譯。 巨集定義是C語言提供的三種預處理功能的其中一種。巨集定義和操作符的區別是:巨集定義是替換,不做計算,也不做表示式求解。 巨集定義又稱為巨集代換、巨集替換,簡稱“巨集”。 格式: 其中的識別符號就是所謂的符號常量,也

ANPM-Apache_httpd-Nginx-PHP-MySQL 官方編譯包源(Pre-Built Packages Repository)收集

apache httpd nginx php mysql ANPM-Apache_httpd-Nginx-PHP-MySQL 官方預編譯包源(Pre-Built Packages Repository)收集Apache_httpdNginxhttp://nginx.org/en/linux

mysql sp 練習遊標和編譯

prepare book from oop hand locate exist ont alloc create procedure Jack_count_cur_dual() BEGIN DECLARE tb_name VARCHAR(50); DECLARE done

emacs+Latex 設定xelatex編譯命令,以及功能

剛安裝了AUCTex,但是一般寫中文的時候經常會用到xeCJK包和xelatex編譯命令,但是AUCTex預設不提供對這些的支援,在網上找了很多資料,找到一個比較笨的解決方案: 使用 M-x customize-group 然後輸入tex-command 就可以開啟latex的配置介面了,這裡有

prepare 編譯SQL:Mysql

預編譯SQL: SQL程式碼 prepare pstmt from 'select a from table';   上面這句SQL建立了一個預編譯的SQL。名為pstmt,這個預編譯SQL的存活期就是當前的會話,也就是當前的資料庫連線。 如果連線一斷開 ,那就會消失。 from後面跟的就是要進行編譯的

MySQL的JDBC驅動原始碼解析 編譯開啟

一、背景         現在我們淘寶持久化大多數是採用iBatis+MySQL做開發的,大家都知道,iBatis內建引數,形如#xxx#的,均採用了sql預編譯的形式,舉例如下: <span style="font-size:18px;"><sel

php-文件功能

刪除文件 lin ont lena amp wim multipart move load php-文件預覽 上一篇博客是上傳功能,本篇是上傳後圖片預覽和更改: 代碼如下: 1.yulan.php <!DOCTYPE html PUBLIC "-//W3C//

IIS編譯提升載入速度

microsoft -i for 感覺 初始化 重新 -m 選擇 req 當我們把站點部署在IIS7或IIS6S的時候,每當IIS或是ApplicationPool重新啟動後,第一次請求站點反應總是非常慢。原因大家都知道(不知道能夠參考這個動畫說明ASP.NET網

SQL攻擊-編譯--緩存

可維護性 ins 可讀性 問號 wid 都是 比較 緩存 query PreparedStatement l 它是Statement接口的子接口; l 強大之處: 防SQL攻擊; 提高代碼的可讀性、可維護性; 提高效率! l 學習PreparedS

C編譯

class copy lin turn -- urn ces stdio.h std /* ============================================================================ Name

Navicat for MySQL用ssh功能連接遠程數據庫

net window blog src windows borde 點擊 文章 遠程 轉載自:http://holy2010.blog.51cto.com/1086044/518431 實現用本地的ssh隧道起到加密功能 在windows平臺上運行Navicat for

mysql慢查詢功能詳解

mysql 慢查詢 優化有人的地方就有江湖,數據庫也是,sql優化這個問題,任重道遠,我們總是禁不住有爛sql。怎麽辦呢,還好各大數據庫都有相關爛sql的收集功能,而mysql的慢查詢收集也是異曲同工,配合分析sql的執行計劃,這個優化就有了搞頭了。開啟mysql慢查詢日誌1.查看當前慢查詢設置情況#查看慢查

VC++ 使用編譯

radius 而已 tools filters mpi 鏈接 res 普通 mov 一、使用默認的預編譯頭 要使用預編譯頭,我們必須指定一個頭文件,這個頭文件包含我們不會經常改變的代碼和其他的頭文件,然後我們用這個頭文件來生成一個預編譯頭文件(.pch文件),想

談下mysql處理基礎

意思 fault pre 連接 發現 myisam 定量 ont 預編譯 傳統的操作數據庫方法有兩種: 先寫一條sql語句,然後通過mysqli->query($sql)去操作數據庫(此處使用的是mysqli擴展庫)。這樣操作並不會有什麽大的錯誤,但是當要插入上千條

編譯封裝

cti array etc 元素 傳遞 param name 名稱 結構 /** * 獲取查詢結果並封裝為一個對象數組 * @param $sql 需要執行的SQL語句 * @param array $arr 預編譯語