从一个表中选择数据并将另一个表连接到主“密钥”是非常慢的

时间:2014-10-13 05:40:50

标签: mysql sql join

我有两个表,一个客户端将使用用户名进行搜索,该用户名将在用户表中搜索记录,然后搜索用户ID,然后搜索rooms表并返回结果,但是我当前的代码看起来很完整慢。

我的房间表中有大约750,000条记录,我的用户表中有大约550,000条记录,因此我的结果大约需要5-7秒才能显示回客户端,是否有替代我的代码?

SELECT
    `rooms`.`id`,
    `rooms`.`caption`,
    `rooms`.`description`,
    `rooms`.`roomtype`,
    `rooms`.`owner`,
    `rooms`.`state`,
    `rooms`.`category`,
    `rooms`.`users_now`,
    `rooms`.`users_max`,
    `rooms`.`model_name`,
    `rooms`.`score`,
    `rooms`.`allow_pets`,
    `rooms`.`allow_pets_eat`,
    `rooms`.`room_blocking_disabled`,
    `rooms`.`allow_hidewall`,
    `rooms`.`password`,
    `rooms`.`wallpaper`,
    `rooms`.`floor`,
    `rooms`.`landscape`,
    `rooms`.`floorthick`,
    `rooms`.`wallthick`,
    `rooms`.`mute_settings`,
    `rooms`.`kick_settings`,
    `rooms`.`ban_settings`,
    `rooms`.`chat_mode`,
    `rooms`.`chat_speed`,
    `rooms`.`chat_size`,
    `rooms`.`trade_settings`,
    `rooms`.`group_id`,
    `rooms`.`tags`,
    `rooms`.`push_enabled`,
    `rooms`.`pull_enabled`,
    `rooms`.`enables_enabled`,
    `rooms`.`respect_notifications_enabled`
FROM
    `rooms`
JOIN `users` ON `users`.`id` = `rooms`.`owner`
WHERE
    `users`.`username` = 'query'
ORDER BY
    `rooms`.`users_now` DESC
LIMIT 50

解释计划:

1   SIMPLE  users   const   PRIMARY,id,username username    128 const   1   Using index
1   SIMPLE  rooms   index   owner   users_now   4       50  Using where

我已将适当的列编入索引,但似乎仍然会得到缓慢的结果。谢谢!

2 个答案:

答案 0 :(得分:0)

您的查询看起来很好,而且记录数量也不是很高。

确保users.id和rooms.owner都已编入索引。

您是否需要ORDER BY - 如果需要filesort,这可能会导致性能问题。如果是这样的话,您可以采取few项来提高服务器性能。

EXPLAIN可能有助于缩小问题范围。

答案 1 :(得分:0)

正如我所看到的,您的结果基于users表,但应包含来自teh rooms表的数据。您可以通过两个查询而不是一个查询立即获得结果。首先获取您的users.id,然后获取该结果并在房间表中搜索匹配的所有者。

select users.id from users where username='search'

现在使用您刚刚获得的users.id数组为您的房间运行一个全新的查询。 ForEach Code取决于您正在使用的脚本语言。

虽然我承认这会给您的脚本带来更多努力,但它肯定会立即提升您的速度。如果您的用户结果有多个记录(例如:如果会有多个" users.id和#34;记录返回,这种方法仍然会比较清晰,这仍然有效)。如果有多条记录,您可以构建一个如下所示的数组,以允许单个查询获取所有房间:

select * from rooms where owner in ('id1','id2','id3')

另一种方法是:

select * from rooms where owner in (select users.id from users where username='search')

这种方法更简单,看起来很便宜,但效果很好。它不会返回用户数据,只返回房间数据。第一种方法允许您捕获第一个查询的用户数据和第二个查询的房间数据。