Mysql 将order by与联接结合使用时查询速度较慢

Mysql 将order by与联接结合使用时查询速度较慢,mysql,Mysql,如下表所示: CREATE TABLE `webs_shoutbox` ( `shoutID` int(11) NOT NULL AUTO_INCREMENT, `date` int(14) NOT NULL DEFAULT '0', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', `message` varchar(255) CHARACTER S

如下表所示:

CREATE TABLE `webs_shoutbox` (
  `shoutID` int(11) NOT NULL AUTO_INCREMENT,
  `date` int(14) NOT NULL DEFAULT '0',
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`shoutID`),
  KEY `shoutID` (`shoutID`),
  KEY `name` (`name`(191))
) ENGINE=InnoDB AUTO_INCREMENT=62982 DEFAULT CHARSET=utf8 COLLATE=utf8_roman_ci |

CREATE TABLE `webs_user` (
  `userID` int(11) NOT NULL AUTO_INCREMENT,
  `registerdate` int(14) NOT NULL DEFAULT '0',
  `lastlogin` int(14) NOT NULL DEFAULT '0',
  `username` varchar(255) COLLATE utf8_roman_ci NOT NULL DEFAULT '',
  `password` varchar(255) COLLATE utf8_roman_ci NOT NULL DEFAULT '',
  `nickname` varchar(255) COLLATE utf8_roman_ci NOT NULL DEFAULT '',
   ....,
   ....,
  PRIMARY KEY (`userID`),
  KEY `nickname` (`nickname`),
  KEY `userID` (`userID`)
) ENGINE=MyISAM AUTO_INCREMENT=3366 DEFAULT CHARSET=utf8 COLLATE=utf8_roman_ci 
webs\u user
表包含约4k条记录,
webs\u shoutbox
包含约100k条记录

我想使用
左连接查询数据库并从两个表中获取数据

select shoutID, date, name, message, webs_user.userID
from webs_shoutbox 
left join webs_user on webs_shoutbox.name = webs_user.username 
limit 10;
这将按照预期的方式运行,并将很快返回结果(在毫秒范围内)。但是对于我的查询,我需要按日期或截止日期排序,以便获得最新的。因此,我添加了一个
orderby
语句:

select shoutID, date, name, message, webs_user.userID  
from webs_shoutbox 
left join webs_user on webs_shoutbox.name = webs_user.username  
order by shoutID desc 
limit 10;
突然,这个查询需要13-14秒!?我真的被这个巨大的性能问题弄糊涂了。经过大量的阅读和谷歌搜索,我无法找到为什么它在主键字段上的排序工作如此糟糕。使用order by语句在
webs\u shoutbox
表上执行select时,效果良好。只有与
join
结合使用,性能才会下降


这可能是什么原因造成的?为什么要花这么长时间才能完成看似快速的操作(在PK/索引上排序)?

确保PK有一个用于连接的哈希索引和一个用于排序的btree索引。

试试这个(我希望它能起作用,因为“order by”只限于一个表):

一般来说,最好不要使用text/char/varchar字段作为关系的手段(即外键)。使用整型字段并为其编制索引的速度更快。

请尝试以下操作

SELECT ws.shoutID, ws.date, ws.name, ws.message, webs_user.userID FROM
    (select shoutID, date, name, message 
    from webs_shoutbox 
    order by shoutID
    limit 10) as ws
left join webs_user on ws.name = webs_user.username  
order by shoutID desc limit 10

当您选择just with LIMIT MySQL时,请选择前10条记录并停止。ORDERBY语句强制MySQL处理所有记录(并对它们进行排序),因此预计需要更多的时间time@Stan:此表的
主键
shoutID
上的排序是否应该快速进行?应该如此。我可能错了,但申请加入结果时可能会很慢。您可以尝试从webs\u shoutbox获取10条有序记录,并将结果与webs\u用户连接。这应该更快。额外奖金-您不需要加入太多records@Stan:关于如何使用SQL实现这一点,您能给我一些提示或示例吗?我天真地希望mysql足够聪明,可以先进行排序和限制,然后再进行加入。我怎样才能用SQL来告诉mysql呢?作为回答,我发布了一个示例谢谢,这个查询正在做它应该做的事情(大约5毫秒)!我不知道使用这种子查询/语法。感谢您在执行加入之前演示如何限制结果。感谢您的回答。在修复了一些小的语法错误后,此查询的执行速度仍然非常慢(13秒)。用户Stan发布了一些相同的查询,但在子查询中限制了结果,这似乎是一个很好的解决方案。我知道使用text/varchar不是处理表之间关系的好方法,但我继承了这个数据库,如果它在这些字段上进行连接时表现足够好的话……我在子查询中使用了MS SQL Server语法。固定的。
SELECT ws.shoutID, ws.date, ws.name, ws.message, webs_user.userID FROM
    (select shoutID, date, name, message 
    from webs_shoutbox 
    order by shoutID
    limit 10) as ws
left join webs_user on ws.name = webs_user.username  
order by shoutID desc limit 10