第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?


問題:

MySQL 在處理臨時結果集(UNION 運算 / 聚合運算等)時,會用到內部臨時表(internal temporary table)。

那麼內部臨時表會使用多少內存呢?


實驗:

我們先創建一個測試用的數據庫,


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

然後準備好數據,


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

我們使用一個帶 UNION 的子表,使執行計劃會使用內部臨時表:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

可以看到執行計劃確實使用了臨時表:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

下面我們另起一個 session,用 performance_schema 對內存進行觀察:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

在主 session 中,探查其連接號,並找到線程號:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

在 performance_schema 中,確認其內存分配的統計初始狀態:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

在主 session 中執行 SQL:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

在 performance_schema 中,查看其內存分配:

第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

可知在這個 SQL 的處理過程中,總共分配了 4M 多的內存用於內部臨時表:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

我們都知道內存臨時表是 memory(heap) 引擎格式的表,那我們手工建一個顯式的內存表,應當和內存臨時表使用的內存相同,來試驗一下。

在主 session 中創建一張內存表,將數據插入到內存表中:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

觀察 performance_schema 可知:內存表駐留在內存裡的字節數與之前臨時表使用的字節數相同。


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?


結論

我們通過 performance_schema 觀察了 memory 引擎的內存分配,由此推算了內部臨時表的內存佔用情況。

MySQL 在其他元數據中,諸如 information_schema.INNODB_TEMP_TABLE_INFO 中,並不展示內部臨時表的信息,如圖:


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?

另外值得注意的是:memory 引擎會多劃分出不少空間,比如本例中我們的數據是 300025 行 * 4 字節 =~ 1.2M,而引擎分出了 4M 多的內存來進行存儲。

因此如果進行估算時,需要將數據量乘以一個較大的係數,才能準確估算。


小貼士:

我們是第二次用到了 dbdeployer,介紹一下其身世:

dbdeployer 的前身是著名的 mysql-sandbox,是著名博主 Giuseppe Maxia 的扛鼎之作(http://datacharmer.blogspot.com),可以極其方便地搭建 MySQL 多種架構的測試環境,命令簡單優雅。

今後在實驗中,我們會多次用到 dbdeployer,或者使用 MySQL 容器進行快速搭建和試驗。


關於 MySQL 的技術內容,你們還有什麼想知道的嗎?趕緊留言告訴小編吧!


第05問:MySQL 在處理臨時結果集時,內部臨時表會使用多少內存?


分享到:


相關文章: