本文介紹了如何在PolarDB MySQL版的只讀節點上創建自定義臨時表。
背景信息
PolarDB為了提高查詢性能和數據隔離性,引入了臨時表機制。臨時表可以存儲查詢過程中的中間結果,減少重復掃描,提高查詢效率,并確保不同會話之間的數據隔離。然而,在讀寫分離的PolarDB集群中,對臨時表的創建和DML操作會增加寫節點的負擔。為了解決這個問題,PolarDB擴展了臨時表的功能,支持在只讀節點上創建和查詢臨時表操作,并建議使用存儲過程進行批量封存和調用處理操作,從而優化性能和減少寫節點的負載。
版本要求
版本需滿足以下條件之一:
PolarDB MySQL版MySQL 8.0.1版本,且修訂版本為8.0.1.1.28及以上。
PolarDB MySQL版MySQL 8.0.2版本,且修訂版本為8.0.2.2.5及以上。
PolarDB MySQL版MySQL 5.7版本,且修訂版本為5.7.1.0.35及以上。
使用限制
只讀節點僅支持MEMORY或MYISAM引擎創建自定義臨時表,讀寫節點可以支持在MEMORY和INNODB引擎下創建自定義臨時表。由于臨時表的生命周期為Session級別,目前Proxy不支持自動路由創建臨時表和后續增刪改查到同一個節點。因此需要結合PROXY HINT方式指定集群節點,了解更多詳細請參見HINT語法使用說明。
使用方法
在PolarDB MySQL版中,臨時表通常使用CREATE TEMPORARY TABLE語句創建,它們的作用域限制在創建它們的會話中,一旦會話結束,臨時表及其數據就會被自動銷毀。
創建只讀自定義臨時表
需要在SQL語句前加上/*force_node='pi-bpxxxxxxxx'*/強制指定這條SQL的路由方向,否則會收到如下錯誤Table 'test.new_tbl' doesn't exist
。
請創建臨時表時指定相關節點,否則會路由到寫節點。
/*force_node='pi-bpxxxxxxxx'*/ CREATE TEMPORARY TABLE new_tbl (c1 int PRIMARY KEY, c2 varchar(100)) ENGINE=MEMORY;
/*force_node='pi-bpxxxxxxxx'*/ CREATE TEMPORARY TABLE new_tbl (c1 int PRIMARY KEY, c2 varchar(100)) ENGINE=MYISAM;
/*force_node='pi-bpxxxxxxxx'*/ CREATE TEMPORARY TABLE new_tbl SELECT * FROM orig_tbl LIMIT 0;
-- SQL語句運行之前需添加/*force_node='pi-bpxxxxxxxx'*/來強制指定這條SQL的路由方向
/*force_node='pi-bpxxxxxxxx'*/ INSERT INTO new_tbl VALUES(1, 'test_string');
/*force_node='pi-bpxxxxxxxx'*/ SELECT * FROM new_tbl;
在只讀節點上執行臨時表
請確保已成功創建只讀節點。如果尚未創建只讀節點,請參考相關文檔增加只讀節點。
請確保數據庫集群已成功連接。如尚未連接,請參考連接數據庫集群相關文檔進行連接操作。從而驗證只讀節點是否支持臨時表操作。
mysql -u <user> -h test-4.xxx.polardb.aliyuncs.com -P3306 -p<pwd>
SELECT * FROM new_tbl;
+----+-------------+
| c1 | c2 |
+----+-------------+
| 1 | test_string |
+----+-------------+
1 row in set (0.07 sec)
mysql> SHOW CREATE TABLE new_tbl;
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| new_tbl | CREATE TEMPORARY TABLE `new_tbl` (
`c1` int(11) NOT NULL,
`c2` varchar(100) DEFAULT NULL,
PRIMARY KEY (`c1`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.08 sec)
通過存儲過程創建自定義臨時表
通過集群地址或者RW節點創建存儲過程。
CREATE TABLE t1 (c1 int PRIMARY KEY, c2 varchar(100)); INSERT INTO t1 VALUES(1, 'test_string'); DELIMITER //; CREATE PROCEDURE tmp_p0() BEGIN CREATE TEMPORARY TABLE IF NOT EXISTS tmp_table engine = MYISAM AS SELECT * FROM t1 limit 10; SELECT * FROM tmp_table; DROP TABLE tmp_table; END //; DELIMITER ;
指定在只讀節點上執行存儲過程。
/*force_node='pi-bpxxxxxxxx'*/ call tmp_p0();