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

如何使用或使用多列为mysql查询编制索引,mysql,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

我的问题是:

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)
有人能告诉我为该查询建立该表索引的正确方法吗?如果我删除了orderby,那么type将转到ALL


感谢您的帮助

您无法为该查询的表编制索引,但如果您在
发送者
接收者
上放置两个不同的索引,则另一个索引将运行得很快:

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

我相信您需要编写一个索引,其中两列都有第一个位置。在您的案例中,添加:

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

发送者
上有一个索引,在
接收者
上有一个索引,应该足以进行此类查询:

CREATE INDEX ind_sender
    ON privatemessages69 (sender) ;

CREATE INDEX ind_recipient 
    ON privatemessages69 (recipient) ;
我不认为如果你用
UNION
来编写它会更快


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

我现在无法测试,但它可能会删除文件排序


您仍然可以编辑问题并在结尾添加:

  • 按以下顺序排列的时间:(3-4秒) (你说)
  • 中的总行数 表:
  • 包含的行数
    收件人=19
  • 包含的行数
    sender=19
  • 查询的行数 返回:
我昨天对总共约30万行进行的一些测试显示,查询在不到一秒钟的时间内运行。速度慢可能是MySQL的配置设置造成的


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

有没有提到原因?@Kevin Peno:Mysql不能使用跨越两列的索引,如果两列都使用
组合。请看一看解释索引用法的mysql文档(最后一个示例框):@soulmerge,如果您在收件人上添加单独的索引,那么您可以使用
select*from privatemessages69,其中sender=19或receiver=19
,它将在这两者上使用and索引。如果您不更改表,因此不添加索引,那么您的代码将不会在
收件人上使用索引,因为它不是复合索引的最左边部分,那么您的代码如何比使用简单的索引更好?@soulmerge:您(或者我应该说MySQL的在线文档)在这一点上是错误的。两个(或多个)单独字段上的两个(或多个)索引可以与或一起使用,就像Brian的查询一样。我检查的版本(5.0.51)在解释中显示了
type:index\u merge
。这是指向
index merge
的链接:这是在从查询中删除ORDER BY时使用type:all这显然是最快的方法。我想我现在唯一真正的问题是通过减慢查询速度来排序。你知道一个很好的加速方法吗?(我应该问一个新问题吗?这里是新问题)谢谢你的帮助!
CREATE INDEX ind_sender_2
    ON privatemessages69 (sender, id) ;

CREATE INDEX ind_recipient_2
    ON privatemessages69 (recipient, id) ;