文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  其他儲存引擎  /  MEMORY 儲存引擎

18.3 MEMORY 儲存引擎

MEMORY 儲存引擎 (先前稱為 HEAP) 會建立特殊用途的表格,其內容會儲存在記憶體中。由於資料容易受到當機、硬體問題或電源中斷的影響,因此這些表格僅能用作臨時工作區域或從其他表格提取資料的唯讀快取。

表 18.4 MEMORY 儲存引擎功能

功能 支援
B 樹索引
備份/時間點復原 (在伺服器中實作,而不是在儲存引擎中實作。)
叢集資料庫支援
叢集索引
壓縮資料
資料快取 不適用
加密資料 是 (透過加密函數在伺服器中實作。)
外部鍵支援
全文搜尋索引
地理空間資料類型支援
地理空間索引支援
雜湊索引
索引快取 不適用
鎖定精細度 表格
MVCC
複寫支援 (在伺服器中實作,而不是在儲存引擎中實作。) 有限制 (請參閱本節稍後的討論。)
儲存限制 RAM
T 樹索引
交易
更新資料字典的統計資料

何時使用 MEMORY 或 NDB 叢集

希望部署應用程式使用 MEMORY 儲存引擎來處理重要、高可用性或經常更新的資料的開發人員,應該考慮 NDB 叢集是否是更好的選擇。MEMORY 引擎的典型使用案例包含以下特性

  • 涉及暫時性、非關鍵資料 (例如工作階段管理或快取) 的操作。當 MySQL 伺服器停止或重新啟動時,MEMORY 表格中的資料會遺失。

  • 用於快速存取和低延遲的記憶體內儲存。資料量可以完全放入記憶體中,而不會導致作業系統將虛擬記憶體頁面換出。

  • 唯讀或大部分唯讀的資料存取模式 (有限的更新)。

NDB 叢集提供與 MEMORY 引擎相同的功能,並具有更高的效能等級,並提供 MEMORY 無法提供的其他功能

  • 資料列層級鎖定和多執行緒操作,可減少用戶端之間的競爭。

  • 即使在包含寫入的陳述式組合中,也具有可擴展性。

  • 可選擇使用磁碟支援操作,以確保資料持久性。

  • 具有無單點故障的共用無架構和多主機操作,可實現 99.999% 的可用性。

  • 跨節點自動資料分佈;應用程式開發人員無需製作自訂的分散或分割解決方案。

  • 支援 MEMORY 不支援的可變長度資料類型 (包括 BLOBTEXT)。

分割

MEMORY 表格無法分割。

效能特性

MEMORY 效能受到單執行緒執行和處理更新時表格鎖定額外負荷所導致的競爭所限制。當負載增加時,這會限制可擴展性,特別是對於包含寫入的陳述式組合而言。

儘管 MEMORY 表格會進行記憶體內處理,但在繁忙的伺服器上、一般用途查詢或讀/寫工作負載下,它們不一定比 InnoDB 表格快。尤其是,執行更新時涉及的表格鎖定會減慢多個工作階段同時使用 MEMORY 表格的速度。

根據對 MEMORY 表格執行的查詢種類,您可以將索引建立為預設的雜湊資料結構 (用於根據唯一索引鍵查詢單一值),或是一般用途的 B 樹資料結構 (用於所有涉及相等、不相等或範圍運算子 (例如小於或大於) 的查詢)。以下章節說明建立這兩種索引的語法。常見的效能問題是在 B 樹索引更有效率的工作負載中使用預設雜湊索引。

MEMORY 表格的特性

MEMORY 儲存引擎不會在磁碟上建立任何檔案。表格定義會儲存在 MySQL 資料字典中。

MEMORY 表格具有以下特性

  • MEMORY 表格的空間是以小區塊配置的。表格在插入時使用 100% 的動態雜湊。不需要溢位區域或額外的索引鍵空間。不需要額外空間來放置可用清單。刪除的資料列會放入連結清單中,並在您將新資料插入表格時重複使用。MEMORY 表格也沒有一般與雜湊表格中的刪除加上插入相關聯的問題。

  • MEMORY 表格使用固定長度的資料列儲存格式。可變長度類型 (例如 VARCHAR) 會使用固定長度儲存。

  • MEMORY 表格不能包含 BLOBTEXT 資料行。

  • MEMORY 包含對 AUTO_INCREMENT 資料行的支援。

  • TEMPORARY MEMORY 表格會與所有用戶端共用,就像任何其他非 TEMPORARY 表格一樣。

MEMORY 表格的 DDL 操作

若要建立 MEMORY 表格,請在 CREATE TABLE 陳述式上指定子句 ENGINE=MEMORY

CREATE TABLE t (i INT) ENGINE = MEMORY;

如引擎名稱所示,MEMORY 表格會儲存在記憶體中。它們預設使用雜湊索引,這使得它們對於單一值查詢非常快,並且對於建立臨時表格非常有用。但是,當伺服器關閉時,儲存在 MEMORY 表格中的所有資料列都會遺失。表格本身會繼續存在,因為它們的定義會儲存在 MySQL 資料字典中,但當伺服器重新啟動時,它們會是空的。

此範例示範您可能如何建立、使用和移除 MEMORY 表格

mysql> CREATE TABLE test ENGINE=MEMORY
           SELECT ip,SUM(downloads) AS down
           FROM log_table GROUP BY ip;

mysql> SELECT COUNT(ip),AVG(down) FROM test;

mysql> DROP TABLE test;

MEMORY 表格的最大容量受限於 max_heap_table_size 系統變數,其預設值為 16MB。若要對 MEMORY 表格強制執行不同的容量限制,請變更此變數的值。對於 CREATE TABLE 或後續的 ALTER TABLETRUNCATE TABLE 所生效的值,將會用於該表格的整個生命週期。重新啟動伺服器也會將現有 MEMORY 表格的最大容量設定為全域的 max_heap_table_size 值。您可以如同本節稍後所述,設定個別表格的大小。

索引

MEMORY 儲存引擎同時支援 HASHBTREE 索引。您可以透過新增 USING 子句來為給定的索引指定其中一種,如下所示

CREATE TABLE lookup
    (id INT, INDEX USING HASH (id))
    ENGINE = MEMORY;
CREATE TABLE lookup
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;

關於 B 樹和雜湊索引的一般特性,請參閱 第 10.3.1 節「MySQL 如何使用索引」

MEMORY 表格每個表格最多可有 64 個索引、每個索引 16 個欄位,以及 3072 位元組的最大金鑰長度。

如果 MEMORY 表格的雜湊索引具有高度的金鑰重複 (許多索引項目包含相同的值),則影響金鑰值的表格更新和所有刪除操作將會明顯變慢。這種減速的程度與重複程度成正比(或與索引基數成反比)。您可以使用 BTREE 索引來避免這個問題。

MEMORY 表格可以有非唯一金鑰。(這是雜湊索引實作中不常見的功能。)

索引的欄位可以包含 NULL 值。

使用者建立的表格和暫存表格

MEMORY 表格的內容會儲存在記憶體中,這是 MEMORY 表格與伺服器在處理查詢時動態建立的內部暫存表格所共有的屬性。然而,這兩種表格的不同之處在於,MEMORY 表格不受儲存轉換的限制,而內部暫存表格則會受限。

載入資料

若要在 MySQL 伺服器啟動時填入 MEMORY 表格,您可以使用 init_file 系統變數。例如,您可以將諸如 INSERT INTO ... SELECTLOAD DATA 之類的陳述式放入檔案中,以從持久資料來源載入表格,並使用 init_file 來命名該檔案。請參閱 第 7.1.8 節「伺服器系統變數」第 15.2.9 節「LOAD DATA 陳述式」

MEMORY 表格和複製

當複製來源伺服器關閉並重新啟動時,其 MEMORY 表格會變為空白。為了將此效果複製到複本,來源第一次在啟動後使用給定的 MEMORY 表格時,它會記錄一個事件,通知複本必須透過在二進位日誌中寫入該表格的 TRUNCATE TABLE 陳述式來清空該表格。當複本伺服器關閉並重新啟動時,其 MEMORY 表格也會變為空白,並且它會將 TRUNCATE TABLE 陳述式寫入其本身的二進位日誌,該日誌會傳遞給任何下游複本。

當您在複製拓撲中使用 MEMORY 表格時,在某些情況下,來源上的表格和複本上的表格可能會有所不同。若要瞭解如何處理每種情況以防止過時的讀取或錯誤,請參閱 第 19.5.1.22 節「複製和 MEMORY 表格」

管理記憶體使用量

伺服器需要足夠的記憶體來維護所有同時在使用的 MEMORY 表格。

如果您從 MEMORY 表格中刪除個別列,則記憶體不會被回收。只有當整個表格被刪除時,記憶體才會被回收。先前用於已刪除列的記憶體會被重新用於同一個表格內的新列。若要在您不再需要 MEMORY 表格的內容時釋放它使用的所有記憶體,請執行 DELETETRUNCATE TABLE 以移除所有列,或使用 DROP TABLE 完全移除表格。若要釋放已刪除列使用的記憶體,請使用 ALTER TABLE ENGINE=MEMORY 強制重新建置表格。

MEMORY 表格中一列所需的記憶體是使用以下運算式計算的

SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))

ALIGN() 表示一個進位因數,使列長度成為 char 指標大小的整數倍。sizeof(char*) 在 32 位元電腦上為 4,在 64 位元電腦上為 8。

如前所述,max_heap_table_size 系統變數設定 MEMORY 表格最大容量的限制。若要控制個別表格的最大容量,請在建立每個表格之前設定此變數的階段作業值。(除非您打算將該值用於所有用戶端建立的 MEMORY 表格,否則請勿變更全域 max_heap_table_size 值。)以下範例建立兩個 MEMORY 表格,其最大容量分別為 1MB 和 2MB

mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)

mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)

如果伺服器重新啟動,這兩個表格都會還原為伺服器的全域 max_heap_table_size 值。

您也可以在 MEMORY 表格的 CREATE TABLE 陳述式中指定 MAX_ROWS 表格選項,以提供您計畫在其中儲存的列數提示。這並不會讓表格成長超出 max_heap_table_size 值,後者仍然充當最大表格大小的限制。為了能夠彈性地使用 MAX_ROWS,請將 max_heap_table_size 設定為至少與您希望每個 MEMORY 表格能夠成長的值一樣高。

其他資源

專門討論 MEMORY 儲存引擎的論壇位於 https://forums.mysql.com/list.php?92