如何使用或使用多列索引mysql查询

时间:2011-04-26 22:40:17

标签: mysql

我的查询:

SELECT * FROM privatemessages69 
WHERE sender='19' OR recipient='19' 
ORDER BY id DESC;

我的表:

CREATE TABLE `privatemessages69` (
  `id` int(11) NOT NULL auto_increment,
  `recipient` int(11) NOT NULL,
  `sender` int(11) NOT NULL,
  `time` int(11) NOT NULL,
  `readstatus` int(11) NOT NULL,
  `message` varchar(255) NOT NULL,
  `messagetype` int(11) NOT NULL,
  `rdeleted` int(11) NOT NULL,
  `sdeleted` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `msgpanel` (`sender`,`recipient`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50000 DEFAULT CHARSET=latin1

说明:

mysql> explain SELECT * FROM privatemessages69 WHERE sender='19' OR recipient='19' ORDER BY id DESC;
+----+-------------+-------------------+-------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table             | type  | possible_keys | key     | key_len | ref  | rows  | Extra       |
+----+-------------+-------------------+-------+---------------+---------+---------+------+-------+-------------+
|  1 | SIMPLE      | privatemessages69 | index | msgpanel      | PRIMARY | 4       | NULL | 50191 | Using where |
+----+-------------+-------------------+-------+---------------+---------+---------+------+-------+-------------+
1 row in set (0.00 sec)

有人可以告诉我为该查询索引此表的正确方法吗?如果我删除了订单,请输入ALL。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

sender上有一个索引,在recipient上有一个索引就足够了这样的查询:

CREATE INDEX ind_sender
    ON privatemessages69 (sender) ;

CREATE INDEX ind_recipient 
    ON privatemessages69 (recipient) ;

如果你用UNION写它,我觉得它会更快。


您也可以尝试添加这两个索引(并删除上面的索引):

CREATE INDEX ind_sender_2
    ON privatemessages69 (sender, id) ;

CREATE INDEX ind_recipient_2
    ON privatemessages69 (recipient, id) ;

我现在无法测试,但它可能会摆脱文件档。


您仍然可以编辑您的问题并在最后添加:

  • ORDER BY的时间:(3-4秒为 你说)
  • 中的总行数 表:
  • 包含的行数 recipient=19
  • 包含的行数 sender=19
  • 查询的行数 返回:

我昨天做的一些测试总共有大约30万行显示查询在不到一秒的时间内运行。缓慢可能是由于MySQL的配置设置。

另外:无论你输入什么(而不是19),查询都需要3-4秒?

答案 1 :(得分:2)

您无法为该查询的表编制索引,但如果您在senderrecipient上放置2个不同的索引,则另一个会快速运行:

SELECT * FROM (
    SELECT * FROM privatemessages69 WHERE sender=19
    UNION
    SELECT * FROM privatemessages69 WHERE recipient=19
) t
ORDER BY id DESC;

答案 2 :(得分:1)

我相信你需要写一个索引,其中两列都有第一个位置。在你的情况下添加:

CREATE INDEX `msgpanel_recp` ON `privatemessages69` (`recipient`,`id`)