查询使用的文件排序

时间:2015-04-03 17:57:37

标签: mysql

我需要哪些类型的索引来避免文件排序?

查询:

SELECT *
FROM (`phppos_messages`)
JOIN `phppos_message_receiver` ON `phppos_messages`.`id`=`phppos_message_receiver`.`message_id`
WHERE `receiver_id` =  '1'
AND `phppos_messages`.`deleted` =  0
ORDER BY `created_at` desc
LIMIT 10000 

说明:

+----+-------------+-------------------------+------+---------------------------------------------------------------+--------------------------------+---------+------------------------+------+-----------------------------+
| id | select_type | table                   | type | possible_keys                                                 | key                            | key_len | ref                    | rows | Extra                       |
+----+-------------+-------------------------+------+---------------------------------------------------------------+--------------------------------+---------+------------------------+------+-----------------------------+
|  1 | SIMPLE      | phppos_messages         | ALL  | PRIMARY                                                       | NULL                           | NULL    | NULL                   |    1 | Using where; Using filesort |
|  1 | SIMPLE      | phppos_message_receiver | ref  | phppos_message_receiver_ibfk_1,phppos_message_receiver_ibfk_2 | phppos_message_receiver_ibfk_1 | 4       | pos.phppos_messages.id |    1 | Using where                 |
+----+-------------+-------------------------+------+---------------------------------------------------------------+--------------------------------+---------+------------------------+------+-----------------------------+

表:

mysql> show create table phppos_messages;
+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table           | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_messages | CREATE TABLE `phppos_messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `message` text COLLATE utf8_unicode_ci NOT NULL,
  `sender_id` int(11) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `deleted` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `phppos_messages_ibfk_1` (`sender_id`),
  CONSTRAINT `phppos_messages_ibfk_1` FOREIGN KEY (`sender_id`) REFERENCES `phppos_employees` (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table phppos_message_receiver;
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                   | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_message_receiver | CREATE TABLE `phppos_message_receiver` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `message_id` int(11) NOT NULL,
  `receiver_id` int(11) NOT NULL,
  `message_read` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `phppos_message_receiver_ibfk_1` (`message_id`),
  KEY `phppos_message_receiver_ibfk_2` (`receiver_id`),
  CONSTRAINT `phppos_message_receiver_ibfk_1` FOREIGN KEY (`message_id`) REFERENCES `phppos_messages` (`id`),
  CONSTRAINT `phppos_message_receiver_ibfk_2` FOREIGN KEY (`receiver_id`) REFERENCES `phppos_employees` (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

2 个答案:

答案 0 :(得分:0)

这是您的查询,用合格的列名称澄清:

SELECT *
FROM `phppos_messages` m JOIN
     `phppos_message_receiver` r
     ON m.`id`= r.`message_id`
WHERE r.`receiver_id` =  '1' AND `m`.`deleted` =  0
ORDER BY m.`created_at` desc
LIMIT 10000 

您可能会对以下索引感到满意:phppos_messages(deleted, created_at, id)phppos_message_receiver(message_id, receiver_id)

但是,如果消息表非常大,这实际上可能无法提高性能 - 即使它消除了文件排序。需要扫描所有未删除的记录以使用order by的索引。

答案 1 :(得分:0)

filesort是ORDER BY created_at desc的结果。在created_at上输入一个键以避免filesort。