我有一个聊天应用程序。我有一个API,它返回用户说话的用户列表。但是,当MySQL达到100000行数据时,需要很长时间才能返回列表消息。 这是我的邮件表MysqL大表查询优化
CREATE TABLE IF NOT EXISTS `messages` (
`_id` int(11) NOT NULL AUTO_INCREMENT,
`fromid` int(11) NOT NULL,
`toid` int(11) NOT NULL,
`message` text NOT NULL,
`attachments` text NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '0',
`date` datetime NOT NULL,
`delete` varchar(50) NOT NULL,
`uuid_read` varchar(250) NOT NULL,
PRIMARY KEY (`_id`),
KEY `fromid` (`fromid`,`toid`,`status`,`delete`,`uuid_read`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=118561 ;
,这是我的用户表(简体)
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(50) DEFAULT '',
`sex` tinyint(1) DEFAULT '0',
`status` varchar(255) DEFAULT '',
`avatar` varchar(30) DEFAULT '0',
`last_active` datetime DEFAULT NULL,
`active` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=15523 ;
这里是我的查询(用户ID为1930)
select SQL_CALC_FOUND_ROWS `u_id`, `id`, `login`, `sex`, `birthdate`, `avatar`, `online_status`, SUM(`count`) as `count`, SUM(`nr_count`) as `nr_count`, `date`, `last_mesg` from
(
(select `m`.`fromid` as `u_id`, `u`.`id`, `u`.`login`, `u`.`sex`, `u`.`birthdate`, `u`.`avatar`, `u`.`last_active` as online_status, COUNT(`m`.`_id`) as `count`, (COUNT(`m`.`_id`)-SUM(`m`.`status`)) as `nr_count`, `tm`.`date` as `date`, `tm`.`message` as `last_mesg` from `messages` as m inner join `messages` as tm on `tm`.`_id`=(select MAX(`_id`) from `messages` as `tmz` where `tmz`.`fromid`=`m`.`fromid`) left join `users` as u on `u`.`id`=`m`.`fromid` where `m`.`toid`=1930 and `m`.`delete` not like '%1930;%' group by `u`.`id`)
UNION
(select `m`.toid as `u_id`, `u`.`id`, `u`.`login`, `u`.`sex`, `u`.`birthdate`, `u`.`avatar`, `u`.`last_active` as online_status, COUNT(`m`.`_id`) as `count`, 0 as `nr_count`, `tm`.`date` as `date`, `tm`.`message` as `last_mesg` from `messages` as m inner join `messages` as tm on `tm`.`_id`=(select MAX(`_id`) from `messages` as `tmz` where `tmz`.`toid`=`m`.`toid`) left join `users` as u on `u`.`id`=`m`.`toid` where `m`.`fromid`=1930 and `m`.`delete` not like '%1930;%' group by `u`.`id`)
order by `date` desc) as `f` group by `u_id` order by `date` desc limit 0,10
请帮助优化此查询
我需要什么, 谁用户ta lked到(姓名,性别,等等) 是什么(从我或给我)的最后一条消息 计数消息(全部) 计数未读邮件(仅限于我)的
查询效果很好,但需要很长时间。
输出必须是这样
您没有提供'EXPLAIN'输出。每个MySQL相关的问题都有。从我可以看到的 - 你正在做一个'LIKE'查询,在开始和结束时都带有通配符 - 表示一个完整的表扫描(所以它遍历整个表的数据)。没有提及配置,所以我们不知道MySQL是否可以正确使用你的硬件。根据这个问题来看,你正在运行默认配置,在机械驱动器上,没有任何优化,如果你必须执行'LIKE'搜索来获取ID ='1930'的用户数据,那么你完全错误地查询它恐怕。 –
我编辑了输出图片的问题。 我添加“user_id +分号”删除列时,用户删除消息。所以在查询中有''m'.'lelete'不像'%1930;%'“。如此删除的消息不被检索。 –
您使用LIKE运算符引用的删除列的目的是什么?如果这是删除消息的用户的ID,它应该是一个像ID一样的INT,如果它拥有一个ID列表(我猜是基于它是一个VARCHAR的事实),那么你应该创建一个单独的连接表来保存这些ID。 – SeanN