同一条GROUP BY查询,只改要不要带上一个真正的TEXT列,再对比新旧两种内部临时表引擎,看TEXT列到底会不会强制临时表落盘。
orders表加一列真正的TEXT类型(note_text),内容和已有的VARCHAR列(note)完全一样,只是类型不同。
代码ALTER TABLE orders ADD COLUMN note_text TEXT; UPDATE orders SET note_text = note; -- 对比: SELECT ym, COUNT(*), SUM(amount) FROM orders GROUP BY ym; -- 只有数字 SELECT ym, MIN(note_text) sample FROM orders GROUP BY ym; -- 带上TEXT列
GROUP BY ym, COUNT(*), SUM(amount)(只有数字列): Created_tmp_disk_tables = 0 GROUP BY ym, MIN(note_text)(带上一个真正的TEXT列): Created_tmp_disk_tables = 1 ← 立刻落盘,不是因为数据量大,是因为列类型
把internal_tmp_mem_storage_engine手动设回旧版的MEMORY引擎后,只聚合数字列的GROUP BY,内部临时表真实还是留在内存里;但只要SELECT列表里出现了一个真正的TEXT类型的列,Created_tmp_disk_tables立刻变成1——这和数据量大小完全无关,因为MySQL经典的MEMORY存储引擎从设计上就不支持存储BLOB/TEXT这类变长大对象,只要内部临时表里需要装下一个TEXT列,MEMORY引擎当场就放弃,直接改用基于磁盘的InnoDB内部临时表。
GROUP BY ym, MIN(note_text)(同样带TEXT列): Created_tmp_disk_tables = 0 ← 换回默认引擎后,同一条查询不再强制落盘
每一步都是本文上面用SHOW STATUS跑出来的原始结果。
SESSION internal_tmp_mem_storage_engine(MEMORY / TempTable)+ SHOW STATUS LIKE 'Created_tmp_disk_tables'