MySQL 5.5.24,Windows 7 64 位。
我有在三列上定义主键的 InnoDB 表:
CREATE TABLE `common_descriptions` (
`object_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
`object_type` varchar(32) NOT NULL DEFAULT '',
`description` mediumtext NOT NULL,
`lang_code` char(2) NOT NULL DEFAULT '',
`object` varchar(12) NOT NULL DEFAULT '',
`object_holder` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`object_id`,`lang_code`,`object`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
我正在执行相当简单的查询(在我看来)应该使用索引返回行
select SQL_NO_CACHE object_id, lang_code, object
from common_descriptions
limit 1
但它创建了 10 个临时表,其中 3 个在磁盘临时表上(通过监控多次确认show status like '%tmp%';
)。object
column 似乎触发了临时表的创建。当我用 (mediumtext) 替换object
(varchar(12)) 时,description
不会创建临时表。explain extended
以上查询:
mysql> explain extended select SQL_NO_CACHE object_id, lang_code, object from co
mmon_descriptions limit 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: common_descriptions
type: index
possible_keys: NULL
key: PRIMARY
key_len: 47
ref: NULL
rows: 49765
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
tmp_table_size
和都max_heap_table_size
设置为16M。
在阅读了关于临时表的文档(http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html)后,我没有看到任何关于为什么要创建临时表的很好的解释案子。为什么会这样?
观察 #1
您需要查看查询优化器看到的内容以及它正在解释的内容
一、仔细看query
没有 WHERE 子句。它正在为无限结果集生成一个临时表。
在查询优化器看来,LIMIT 的优先级较低。为什么 ?
根据MySQL 文档
SELECT
同一页的另一部分内容如下:
使用子句
LIMIT
后,SELECT
必须先生成结果。您的结果没有边界(没有 WHERE 子句)。之后应用 LIMIT。这解释了临时表的创建。
观察#2
您在问题中提到了以下内容
根据临时表上的 MySQL 文档(您的链接)
问题与结果集和第一个要点 ( ) 有很大关系,
Presence of a BLOB or TEXT column in the table
因为 TEXT 字段不能占用内存中的临时表,它直接进入磁盘。这只是冰山一角。当你跑的时候
您基本上阅读了整行。怎么来的 ?
common_descriptions
是用 InnoDB 存储引擎定义的InnoDB 表的主键位于称为聚簇索引的逻辑结构中(内部称为
gen_clust_index
,只有在运行时才能看到SHOW ENGINE INNOD STATUS\G
)该文件说
由于您访问了 PRIMARY KEY (
object_id, lang_code, object
) 的每一列,因此在内部您实际上是在获取每一行(包括description
),这解释了为什么 PRIMARY KEY 检索仍然会在磁盘上产生一个临时表。当您更改 SELECT 列表 (object_id, lang_code, description
) 时,事情显然发生了变化。一点。不会创建内存中的临时表。为什么?MySQL 文档是这样说的:
因此,
Created_tmp_tables
不会因为描述为而增加mediumtext
。它直接进入磁盘。Created_tmp_disk_tables
反而会增加。概括
涉及的因素很多
description
存在MEDIUMTEXT
建议
尝试添加一个
ORDER BY
我在针对单个列 PRIMARY KEY 完成时看到了它。
试试看 !!!