mysql-5.6.24-win32.1432006610MySQL:为什么在使用索引时仍然会'使用filesort'?
我有两个用户消息表。
TMessageBody (id, body)
存储消息的正文。
TMessage (id, uid, folderId, msgBodyId, subject)
存储用户在文件夹中的用户邮件,如收件箱,发件箱。
创建表的SQL:
create table TMessageBody (
id int unsigned not null primary key auto_increment,
body text not null
);
create table TMessage (
id int unsigned not null primary key auto_increment,
uid int unsigned not null,
folderId int unsigned not null,
msgBodyId int unsigned not null,
subject varchar(256) not null
);
一些测试数据:
insert into TMessageBody
(body) values
('Here is body 1')
,('Here is body 2')
,('Here is body 3')
,('Here is body 4')
,('Here is body 5')
,('Here is body 6')
,('Here is body 7')
,('Here is body 8')
,('Here is body 9')
;
insert into TMessage
(uid, folderId, msgBodyId, subject) values
(1, 999, 1, 'Hello jack')
, (1, 999, 2, 'Jack, how are you')
, (1, 888, 3, 'Good morning jack')
, (2, 888, 4, 'I love you, rose')
, (2, 999, 5, 'I love you, rose')
, (3, 888, 6, 'Peter, please call back')
, (3, 999, 7, 'What are you doing, Peter')
, (3, 999, 8, 'Happy birthday, perter')
, (4, 999, 9, 'Let me know if you are ready')
;
索引:
create index Idx_MsgBodyId on TMessage(msgBodyId);
create index Idx_Uid_FolderId on TMessage(uid, folderId);
1.FileSort示出了当folderId
不在WHERE子句
的下面查询由给定用户ID获取包括消息体的所有消息:
SET @uid=3;
SET @folderId=999;
EXPLAIN
SELECT *
FROM TMessage
INNER JOIN TMessageBody
ON TMessage.msgBodyId=TMessageBody.id
WHERE [email protected]
#AND [email protected]
ORDER BY TMessage.id DESC
;
说明结果是:
mysql> EXPLAIN
-> SELECT *
-> FROM TMessage
-> INNER JOIN TMessageBody
-> ON TMessage.msgBodyId=TMessageBody.id
-> WHERE [email protected]
-> #AND [email protected]
-> ORDER BY TMessage.id DESC
-> ;
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
| 1 | SIMPLE | TMessage | ref | Idx_MsgBodyId,Idx_Uid_FolderId | Idx_Uid_FolderId | 4 | const | 3 | Using where; Using filesort |
| 1 | SIMPLE | TMessageBody | eq_ref | PRIMARY | PRIMARY | 4 | test.TMessage.msgBodyId | 1 | NULL |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
2 rows in set (0.00 sec)
2.FileSort消失时folderId
是在WHERE子句
该查询是与上述一个除了WHERE子句为相同:
SET @uid=3;
SET @folderId=999;
EXPLAIN
SELECT *
FROM TMessage
INNER JOIN TMessageBody
ON TMessage.msgBodyId=TMessageBody.id
WHERE [email protected]
AND [email protected]
ORDER BY TMessage.id DESC
;
的EXPLAIN结果是:
mysql> EXPLAIN
-> SELECT *
-> FROM TMessage
-> INNER JOIN TMessageBody
-> ON TMessage.msgBodyId=TMessageBody.id
-> WHERE [email protected]
-> AND [email protected]
-> ORDER BY TMessage.id DESC
-> ;
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-------------+
| 1 | SIMPLE | TMessage | ref | Idx_MsgBodyId,Idx_Uid_FolderId | Idx_Uid_FolderId | 8 | const,const | 2 | Using where |
| 1 | SIMPLE | TMessageBody | eq_ref | PRIMARY | PRIMARY | 4 | test.TMessage.msgBodyId | 1 | NULL |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-------------+
2 rows in set (0.00 sec)
问题:
两个查询之间的区别是folderId
列是否WHERE
子句。根据EXPLAIN结果,这两个查询都使用Idx_Uid_FolderId
索引。我想知道为什么一个显示FileSort,但其他没有。
更新
试图在第一次查询中使用ORDER BY TMessage.folderId, TMessage.id DESC
。但Using filesort
仍然存在于EXPLAIN结果中。
mysql> EXPLAIN
-> SELECT *
-> FROM TMessage
-> INNER JOIN TMessageBody
-> ON TMessage.msgBodyId=TMessageBody.id
-> WHERE [email protected]
-> #AND [email protected]
-> ORDER BY TMessage.folderId, TMessage.id DESC
-> ;
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
| 1 | SIMPLE | TMessage | ref | Idx_MsgBodyId,Idx_Uid_FolderId | Idx_Uid_FolderId | 4 | const | 3 | Using where; Using filesort |
| 1 | SIMPLE | TMessageBody | eq_ref | PRIMARY | PRIMARY | 4 | test.TMessage.msgBodyId | 1 | NULL |
+----+-------------+--------------+--------+--------------------------------+------------------+---------+-------------------------+------+-----------------------------+
2 rows in set (0.06 sec)
谢谢,你很好! – Zach
我试过'在第一个查询中使用TMessage.folderId,TMessage.id DESC'命令,'使用filesort'仍然存在。正如你所说,在大多数情况下是可以接受的,但我仍然想知道为什么在这种情况下。 – Zach
@Zach哦,我会从我的答案中删除那一点 – ESG