mysql-5.6.24-win32.1432006610MySQL: почему все еще используется «fileort» при использовании индексов?
У меня есть две таблицы для сообщений пользователей.
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
не в ИНЕКЕ
Ниже запрос получает все сообщения, в том числе тела сообщения данного идентификатора пользователя:
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 | 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
в ИНЕКЕ
Этот запрос такой же, как показано выше, за исключением ИНЕКЕ:
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 | 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, а другой нет.
Update
Пытались использовать 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
Я попробовал 'ORDER BY TMessage.folderId, TMessage.id DESC' в первом запросе,' Использование filesort' все еще существует. Как вы сказали, это приемлемо в большинстве случаев, но я все еще удивляюсь, почему в этом случае. – Zach
@ Zach ой, я удалю этот бит из моего ответа, тогда – ESG