简体   繁体   中英

Selecting data from one table and joining another table for the main “key” is quite slow

I have two tables, a client would search by using a username which would search the users table for the record, and the user ID and then search through the rooms table and return the results, however my current code appears to be quite slow.

I have around 750,000 records in my rooms table and around 550,000 records in my users table, so my results tend to take around 5-7 seconds to display back to the client, is there an alternative to my code below?

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

Explain plan:

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

I've indexed the appropriate columns, but still seem to get slow results. Thanks!

Your query looks fine, and the amount of records is not all that high.

Make sure users.id and rooms.owner are both indexed.

Do you need the ORDER BY - this can cause performance issues if a filesort is required. There are a few things you can do to improve server performance if thats the case.

An EXPLAIN may help in narrowing down the issue.

As I see it, your results are based on the users table, but should contain data from teh rooms table. You could get your results instantly by two queries instead of one. First get your users.id, then take that result and search the rooms table for a matching owner.

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

Now run a whole new query for your room with the array of users.id you just got. ForEach Code depends on the scripting language you're working in.

While I admit this puts more effort on your script, it will definitely pick up your speed immediately. This will still work if your users results have multiple records (ie: if there will be multiple "users.id" records returned, this method will still be snappy by comparison). If there are multiple records, you can construct an array that looks like this to allow a single query to get all your rooms:

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

Another method is:

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

This method is simpler and seems cheap, but works nicely. It will not return user data, just room data. The first method would allow you to capture user data on the first query and room data on the second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM