久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何進行MySQL Stmt預處理提高效率問題的研究

169次閱讀
沒有評論

共計 2684 個字符,預計需要花費 7 分鐘才能閱讀完成。

如何進行 MySQL Stmt 預處理提高效率問題的研究,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

在 oracle 數據庫中,有一個變量綁定的用法,很多人都比較熟悉,可以調高數據庫效率,應對高并發等,好吧,這其中并不包括我,當同事問我 MySQL 中有沒有類似的寫法時,我是很茫然的,于是就上網查,找到了如下一種寫法:

view sourceprint?DELIMITER $$ 

  set @stmt = select userid,username from myuser where userid between ? and ?; 

  prepare s1 from @stmt; 

  set @s1 = 2; 

  set @s2 = 100; 

  execute s1 using @s1,@s2; 

  deallocate prepare s1; 

$$ 

DELIMITER ;

  用這種形式寫的查詢,可以隨意替換參數,給出代碼的人稱之為預處理,我想這個應該就是 MySQL 中的變量綁定吧……但是,在查資料的過程中我卻聽到了兩種聲音,一種是,MySQL 中有類似 Oracle 變量綁定的寫法,但沒有其實際作用,也就是只能方便編寫,不能提高效率,這種說法在幾個 09 年的帖子中看到:

另一種說法是 MySQL 中的變量綁定是能確實提高效率的,這個是希望有的,那到底有木有,還是自己去試驗下吧。

試驗是在本機進行的,數據量比較小,具體數字并不具有實際意義,但是,能用來說明一些問題,數據庫版本是 mysql-5.1.57-win32 免安裝版。

本著對數據庫不是很熟悉的態度 ^_^, 試驗過程中走了不少彎路,此文以結論為主,就不列出實驗的設計過程,文筆不好,文章寫得有點枯燥,寫出來是希望有人來拍磚,因為我得出的結論是:預處理在有沒有 cache 的情況下的執行效率都不及直接執行…… 我對自己的實驗結果不愿接受。。如果說預處理只為了規范下 Query,使 cache 命中率提高的話個人覺得大材小用了,希望有比較了解的人能指出事實究竟是什么樣子的——NewSilen

實驗準備

第一個文件 NormalQuery.sql

NormalQuery
Set profiling=1;Select * From MyTable where DictID = 100601000004;Select DictID from MyTable limit 1,100;Select DictID from MyTable limit 2,100;/* 從 limit 1,100 到 limit 100,100 此處省略重復代碼 */……Select DictID from MyTable limit 100,100;SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE d:/NormalResults.csv FIELDS TERMINATED BY , LINES TERMINATED BY
;
第二個 sql 文件 StmtQuery.sql

StmtQuery
Set profiling=1;Select * From MyTable where DictID = 100601000004;set @stmt = Select DictID from MyTable limit ?,?;prepare s1 from @stmt;set @s = 100;set @s1 = 101;set @s2 = 102;……set @s100 =200;execute s1 using @s1,@s;execute s1 using @s2,@s;……execute s1 using @s100,@s;SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE d:/StmtResults.csv FIELDS TERMINATED BY , LINES TERMINATED BY
;
做幾點小說明:

1. Set profiling=1; 執行此語句之后,可以從 information_schema.profiling 這張表中讀出語句執行的詳細信息,其實包含不少內容,包括我需要的時間信息,這是張臨時表,每新開一個會話都要重新設置 profiling 屬性才能從這張表中讀取數據

2. Select * From MyTable where DictID = 100601000004;

這行代碼貌似和我們的實驗沒什么關系,本來我也是這么認為的,之所以加這句,是我在之前的摸索中發現,執行過程中有個步驟是 open table,如果是第一次打開某張表,那時間是相當長的,所以在執行后面的語句前,我先執行了這行代碼打開試驗用的表

3. MySQL 默認在 information_schema.profiling 表中保存的查詢歷史是 15 條,可以修改 profiling_history_size 屬性來進行調整,我希望他大一些讓我能一次取出足夠的數據,不過最大值只有 100,盡管我調整為 150,最后能夠查到的也只有 100 條,不過也夠了

4. SQL 代碼我沒有全列出來,因為查詢語句差不多,上面代碼中用省略號表示了,最后的結果是兩個 csv 文件,個人習慣,你也可以把結果存到數據庫進行分析

實驗步驟

重啟數據庫,執行文件 NormalQuery.sql,執行文件 StmtQuery.sql,得到兩個結果文件

再重啟數據庫,執行 StmtQuery.sql,執行文件 NormalQuery.sql,得到另外兩個結果文件

實驗結果分析

每一個 SQL 文件中執行了一百個查詢語句,沒有重復的查詢語句,不存在查詢 cache,統計執行 SQL 的平均時間得出如下結果

從結果中可以看出,無論是先執行還是后執行,NormalQuery 中的語句都比使用預處理語句的要快一些 =.=!

那再來看看每一句查詢具體的情況,Normal 和 Stmt 的 query 各執行了兩百次,每一步的詳細信息如下:

從這里面可以看出,第一個,normalquery 比 stmtquery 少一個步驟,第二個,雖然 stmt 在不少步驟上是優于 normal 的, 但在 executing 一步上輸掉太多,最后結果上也是落敗

  最后,再給出一個查詢緩存的實驗結果,具體步驟就不列了

在查詢緩存的時候,Normal 完勝……

關于如何進行 MySQL Stmt 預處理提高效率問題的研究問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-17發表,共計2684字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 大丰市| 博湖县| 柯坪县| 垦利县| 介休市| 大化| 孝感市| 休宁县| 收藏| 景德镇市| 平阳县| 康定县| 永登县| 丰镇市| 察隅县| 安国市| 双流县| 如东县| 抚宁县| 镇原县| 漳州市| 台北县| 翁源县| 南汇区| 凤城市| 吉木乃县| 安宁市| 德阳市| 玉门市| 准格尔旗| 石门县| 海口市| 宣恩县| 海林市| 昂仁县| 全椒县| 梁平县| 昔阳县| 双城市| 西昌市| 巴塘县|