mysql - 查询使用的文件排序

标签 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)

最佳答案

这是您的查询,用限定的列名称进行了澄清:

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 的索引。

关于mysql - 查询使用的文件排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29437306/

相关文章:

PHP - MySql 数组

PHP + MySQL 导航 : How to load 2 levels in 1 query?

mysql 从字符串列表中获取不同的标记

mysql - mysql中数字列的倒数

mysql - 在 C# 应用程序的 MySQL 数据库中的非常大的表中,简单的选择查询需要更多的时间

mysql - 在mysql中创建带有事务的过程

php - 跨许多 PHP 请求的 MySQL 事务

mysql - 将 curdate() 与基于另一个表的时间连接起来

MySQL 即使没有结果也返回一个值 - IFNULL

php - 您在 codeigniter 中指定了无效的数据库连接组