首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >选择taking 8 seconds。改进想法

选择taking 8 seconds。改进想法
EN

Stack Overflow用户
提问于 2018-06-11 22:47:58
回答 2查看 46关注 0票数 0

我有这个选择来获取聊天(就像facebook收件箱)。它将显示最新的消息,按发送这些消息的用户分组。

代码语言:javascript
运行
复制
SELECT c.id, c.from, c.to, c.sent, c.message, c.recd FROM chat c 
WHERE c.id IN(
  SELECT MAX(id) FROM chat
  WHERE (`to` = 1 and `del_to_status` = '0') or (`from` = 1 and `del_from_status` = '0')
  GROUP BY CASE WHEN 1 = `to` THEN `from` ELSE `to` END
)
ORDER BY id DESC
limit 60

问题是它大约需要8秒。

代码语言:javascript
运行
复制
`chat` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `from` int(11) UNSIGNED NOT NULL,
  `to` int(11) UNSIGNED NOT NULL,
  `message` text NOT NULL,
  `sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `recd` tinyint(1) NOT NULL DEFAULT '0',
  `del_from_status` tinyint(1) NOT NULL DEFAULT '0',
  `del_to_status` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `from` (`from`),
  KEY `to` (`to`),
  FOREIGN KEY (`from`) REFERENCES cadastro (`id`),
  FOREIGN KEY (`to`) REFERENCES cadastro (`id`)
)

有没有什么想法可以索引或者重写这个select来获得更好的速度?

EN

回答 2

Stack Overflow用户

发布于 2018-06-11 23:01:52

我假设chat.id已被编入索引。如果没有,当然你应该添加一个索引。

如果它被编入索引,那么对于子选择,MySQL通常非常慢。

您可以做的一件事是将sub _ select转换为临时表并与其连接。

它看起来会像这样

代码语言:javascript
运行
复制
    CREATE TEMPORARY TABLE IF NOT EXISTS max_chat_ids
                ( INDEX(id) ) 
                ENGINE=MEMORY
                AS ( 'SELECT MAX(id) as id FROM chat
  WHERE (`to` = 1 and `del_to_status` = '0') or (`from` = 1 and `del_from_status` = '0')
  GROUP BY CASE WHEN 1 = `to` THEN `from` ELSE `to` END' );

然后,您只需要连接临时表:

代码语言:javascript
运行
复制
SELECT c.id, c.from, c.to, c.sent, c.message, c.recd FROM chat c 
join max_chat_ids d on c.id=d.id
ORDER BY c.id DESC
limit 60

临时表只在会话期间存在,所以如果您在phpmyadmin中测试这一点,请记住执行这两个查询,并在它们之间加上';‘。

如果你尝试这样做,请分享你的结果。

票数 1
EN

Stack Overflow用户

发布于 2018-06-11 23:01:21

我假设列id已经被编入索引,因为它可能是表的主键。如果不是这样,添加索引:

代码语言:javascript
运行
复制
create index ix1_chat on chat (id);

然后,如果子查询的选择性很好,那么索引将会有所帮助。选择性是select正在读取的行数占总行数的百分比。是50%,5%,还是0.5%?如果它是5%或更低,那么下面的索引将会有所帮助:

代码语言:javascript
运行
复制
create index ix2_chat on chat (`to`, del_to_status, `from`, del_from_status);

顺便说一句,请不要在列名中使用保留字:我说的是来自列的。这只会让每个人的生活变得艰难。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50800463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档