一文搞懂MySQL預編譯

2022-09-24 23:06:10 字數 2534 閱讀 2556

1、預編譯的好處

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

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

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

2、mysql執行預編譯

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

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

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

3、使用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.executequeryhszgz("execute myfun using @str");

while(rs.next())

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

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

while(rs.next())

rs.close();

stmt.close();

con.close();

4、use程式設計客棧mts引數

預設使用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())

pstmt.setstring(1, "b2");

rs = pstmt.executequery();

while(rs.next())

rs.close();

pstmt.close();

con.close();

5、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())

pstmt = con.preparestatement(sql);

pstmt.setstring(1, "b2");

rs = pstmt.executequery();

while(rs.next())

rs.close();

pstmt.close();

con.close();

6、開啟批處理

mysql的批處理也需要通過引數來開啟:

rewritebatchedstatements=true

一文搞懂MySQL的Join

經常聽到2種觀點 其實對於上面的觀點一定程度上是正確的,但不是完全正確。但之所以流傳這麼廣,主要還是沒有搞清楚實際狀態,而根據實際使用中總結出來的一些模糊規律。只有了解的mysql的join實際執行方式,就會知道上面2種觀點是一種模糊的規律,這種規律並不能指導我們實際開發。下面就說說mysql的實際...

一文搞懂MySQL字首索引

通常在開發中我們需要定義字串型別的字段,例如使用者名稱或者使用者郵箱等。假設我們在維護乙個使用者登入系統,使用者表的定義 create table user id bigint unsigned primary key,email varchar 64 engine innodb 如果使用郵箱登入的...

一文搞懂transform skew

目錄 如何理解斜切 skew,先看乙個 demo。在下面的 demo 中,有 4 個正方形,分別是 紅色 不做 skew 變換,綠色 x 方向變換,藍色 y 方向變換,黑色 兩個方向都變換,拖動下面的滑塊可以檢視改變 skew 角度後的效果。切換 selector 可以設定 transform or...