ERROR 1114 (HY000): The table 'adv_date_tmp' is full(Mysql臨時表應用)


場景:需要對現在數據庫的數據進行批量的進行is_del=1的操作,但是遇到一個問題,在執行sql的時候發現sql不能在查詢特定表的時候再嵌套查詢來做update的操作,經過討論,后續我們想到用臨時表的方案來解決這個問題。


開始進行數據測試,進行單用戶的update操作,一切都比較順利沒有任何問題,操作的也是我們想操作的數據,接下來進行批量的數據操作,sql語句運行一會出現如下錯誤:
ERROR 1114 (HY000): The table 'adv_date_tmp' is full
報錯為臨時表已滿,原因是沒有調整mysql的默認臨時表大小導致的報錯。

tmp_table_size
如果內存內的臨時表超過該值,MySQL自動將它轉換為硬盤上的MyISAM表。如果你執行許多高級GROUP BY查詢並且有大量內存,則可以增加tmp_table_size的值。

max_heap_table_size
該變量設置MEMORY (HEAP)表可以增長到的最大空間大小。該變量用來計算MEMORY表的MAX_ROWS值。在已有的MEMORY表上設置該變量沒有效果,除非用CREATE TABLE或TRUNCATE TABLE等語句重新創建表。

默認情況下的臨時表大小不能滿足特定場景的需求,這個時候就需要將臨時表的大小進行動態的調整,一般我們推薦進行set session動態進行會話調整(可以不重啟服務器進行調整),不過也可以通過調整my.cnf的配置來進行永久的調整(需要重啟服務,不推薦這種操作)。

查詢mysql的默認配置臨時表的大小

mysql> show variables like '%tmp_table%';
+----------------+----------+
| Variable_name  | Value    |
+----------------+----------+
| max_tmp_tables | 32       |
| tmp_table_size | 16777216 |
+----------------+----------+
2 rows in set (0.00 sec)

mysql> show variables like '%max_heap%';
+---------------------+----------+
| Variable_name       | Value    |
+---------------------+----------+
| max_heap_table_size | 16777216 |
+---------------------+----------+
1 row in set (0.00 sec)

在線調整臨時表大小

mysql> set session tmp_table_size=1024*1024*1024;
Query OK, 0 rows affected (0.00 sec)

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

mysql> show variables like '%tmp_table%';
+----------------+------------+
| Variable_name  | Value      |
+----------------+------------+
| max_tmp_tables | 32         |
| tmp_table_size | 1073741824 |
+----------------+------------+
2 rows in set (0.00 sec)

mysql> show variables like '%max_heap%';
+---------------------+------------+
| Variable_name       | Value      |
+---------------------+------------+
| max_heap_table_size | 1073741824 |
+---------------------+------------+
1 row in set (0.00 sec)

進行sql語句操作

mysql> CREATE TEMPORARY TABLE IF NOT EXISTS tmp_table ENGINE = MEMORY SELECT adf.opt_id FROM `test`.`test.count` a INNER JOIN `test`.`test.prise` e ON a.prise_id=e.prise_id AND e.is_del=0 AND e.domain IN('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10','test11','test12','test13','test14','test15','test16','test17','test18','test19') INNER JOIN `online`.`FILTER` adf ON adf.user_id=a.user_id AND adf.is_del=0 AND adf.is_global=0 AND adf.`type`='fixed' AND adf.`name` IN ('今天', '昨天', '最近7天', '最近30天', '最近90天', '最近一年') LEFT JOIN `online`.`OPT_ID_DELETE` oid ON adf.opt_id=oid.opt_id WHERE a.is_del=0 AND a.username='admin' AND oid.opt_id is NULL;
Query OK, 101976 rows affected (2 min 3.82 sec)
Records: 101976  Duplicates: 0  Warnings: 0

更新表數據

mysql> UPDATE `online`.`FILTER` SET is_del=1 WHERE opt_id IN( SELECT opt_id FROM tmp_table);

mysql> drop table tmp_table;

Ok,整個操作完成。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM