分佈式 | Prepare Statement 協議遊標可行性

做者:鮑鳳其
愛可生 dble 團隊開發成員,主要負責 dble 需求開發,故障排查和社區問題解答。少說廢話,放碼過來。
本文來源:原創投稿
*愛可生開源社區出品,原創內容未經受權不得隨意使用,轉載請聯繫小編並註明來源。

背景

MySQL JDBC 在執行查詢語句時,默認把查詢的全部結果所有取回放在內存中,若是遍歷很大的表,則可能把內存撐爆。html

辦法 1

查詢語句中使用 limit,offset;這樣咱們會發現取數據的愈來愈慢,緣由是在設置了 offset 以後,MySQL 須要將讀取位置移動到 offset 的位置,隨着 offset 增大,取數據也愈來愈慢;mysql

辦法 2

用數據流的方式取數據,能夠指定 fetch size,這樣每次獲取指定數量的數據行,從而避免 OOM。此種方式的使用方式和原理能夠參見文章:prepare statement 協議
第 2 種方式實際是 MySQL 中的 server-side 遊標,server-side 遊標是使用 MySQL 內部臨時表來實現的。初始的時候,內部臨時表是個內存表,當這個表的大小超過 max_heap_table_size and tmp_table_size 兩個系統變量的最小值的時候(二者的最小值),會被轉換成 MyISAM 表,即落盤存儲。
內部臨時表的使用限制一樣適用於遊標的內部臨時表。sql

MySQL 中的兩種臨時表

外部臨時表

用戶經過 CREATE TEMPORARY TABLE 語句顯式建立的臨時表,這樣的臨時表稱爲外部臨時表。
外部臨時表生命週期:建立後,只在當前會話中可見,當前會話結束的時候,該臨時表也會被自動關閉。
所以,兩個會話能夠存在同名的臨時表,但如有同名的非臨時表時,直到臨時表被刪除,這張表對用戶是不可見的。性能優化

內部臨時表

內部臨時表是一種特殊輕量級的臨時表,用來進行性能優化。這種臨時表會被 MySQL 自動建立並用來存儲某些操做的中間結果。這些操做可能包括在優化階段或者執行階段。
這種內部表對用戶來講是不可見的,可是經過 EXPLAIN 或者 SHOW STATUS 能夠查看 MySQL 是否使用了內部臨時表用來幫助完成某個操做。內部臨時表在 SQL 語句的優化過程當中扮演着很是重要的角色,MySQL 中的不少操做都要依賴於內部臨時表來進行優化。可是使用內部臨時表須要建立表以及中間數據的存取代價,因此用戶在寫 SQL 語句的時候應該儘可能的去避免使用臨時表。ide

內部臨時表有兩種類型

一、HEAP 臨時表

這種臨時表的全部數據都會存在內存中,對於這種表的操做不須要 IO 操做。性能

二、OnDisk 臨時表

顧名思義,這種臨時表會將數據存儲在磁盤上。OnDisk 臨時表用來處理中間結果比較大的操做。若是 HEAP 臨時表存儲的數據大於 MAX_HEAP_TABLE_SIZE(參數參考連接),HEAP 臨時表會被自動轉換成 OnDisk 臨時表。OnDisk 臨時表在 5.7 中能夠經過 INTERNAL_TMP_DISK_STORAGE_ENGINE 系統變量選擇使用 MyISAM 引擎或者 InnoDB 引擎。fetch

臨時表的參數

max_heap_table_size

用戶建立 Memory 表容許的最大 size,這個值和 tmp_table_size 一塊兒使用,限制內部臨時表在內存中的大小。優化

tmp_table_size

內部臨時內存表大小的最大值,不適用於用戶本身建立的 Memory 表
MySQL 中沒有找到限制臨時表磁盤文件大小的參數。設計

DBLE 中的設計

DBLE 中可參考 MySQL 的臨時表的實現,指定一個相似 MAX_HEAP_TABLE_SIZE 的參數。小於這個數值,存放在內存中直接存取,一旦達到這個閾值,一樣落盤處理。server

官方文檔:
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...
相關文章
相關標籤/搜索