简体   繁体   中英

Very slow MySQL query (Left-JOIN, GROUP BY, etc. ?)

I have troubles with the subsequent query, which I submit to a MySQL server. It takes 25s... for (COUNT(*) < 20k)-tables - only featured have 600k rows. However, indexes are created where it should (that is to say : for concerned columns in ON clauses). I tried to remove GROUP BY, which improved the case a bit. But the queries still give a slow response a general rule. I made that post because I could not find a solution into the variety of cases found into stackoverflow. Any suggestion?

SELECT
    doctor.id as doctor_id,
    doctor.uuid as doctor_uuid,
    doctor.firstname as doctor_firstname,
    doctor.lastname as doctor_lastname,
    doctor.cloudRdvMask as doctor_cloudRdvMask,

    GROUP_CONCAT(recommendation.id SEPARATOR ' ') as recommendation_ids,
    GROUP_CONCAT(recommendation.uuid SEPARATOR ' ') as recommendation_uuids,
    GROUP_CONCAT(recommendation.disponibility SEPARATOR ' ') as recommendation_disponibilities,
    GROUP_CONCAT(recommendation.user_id SEPARATOR ' ') as recommendation_user_ids,
    GROUP_CONCAT(recommendation.user_uuid SEPARATOR ' ') as recommendation_user_uuids,

    location.id as location_id,
    location.uuid as location_uuid,
    location.lat as location_lat,
    location.lng as location_lng,

    profession.id as profession_id,
    profession.uuid as profession_uuid,
    profession.name as profession_name
FROM featured as doctor
LEFT JOIN location as location
    ON doctor.location_id = location.id
LEFT JOIN profession as profession
    ON doctor.profession_id = profession.id
LEFT JOIN 
    (
        SELECT 
            featured.id as id, 
            featured.uuid as uuid, 
            featured.doctor_id as doctor_id, 
            featured.disponibility as disponibility,

            user.id as user_id, 
            user.uuid as user_uuid
        FROM featured as featured
            LEFT JOIN user as user
                ON featured.user_id = user.id
            WHERE discr = 'recommendation'
        ) as recommendation
        ON recommendation.doctor_id = doctor.id
WHERE
    doctor.discr = 'doctor'
    AND
    doctor.state = 'Publié'
GROUP BY doctor.uuid

Here comes the EXPLAIN result:

id | select_type | table      | partitions | type   | possible_keys              | key                  | key_len | ref                           | rows   | filtered | Extra       |

1 | SIMPLE      | doctor     | NULL       | ref    | discr,state                | discr                | 767     | const                         | 194653 |    50.00 | Using where |
1 | SIMPLE      | location   | NULL       | eq_ref | PRIMARY                    | PRIMARY              | 4       | doctoome.doctor.location_id   |      1 |   100.00 | NULL        |
1 | SIMPLE      | profession | NULL       | eq_ref | PRIMARY                    | PRIMARY              | 4       | doctoome.doctor.profession_id |      1 |   100.00 | NULL        |
1 | SIMPLE      | featured   | NULL       | ref    | IDX_3C1359D487F4FB17,discr | IDX_3C1359D487F4FB17 | 5       | doctoome.doctor.id            |    196 |   100.00 | Using where |
1 | SIMPLE      | user       | NULL       | eq_ref | PRIMARY                    | PRIMARY              | 4       | doctoome.featured.user_id     |      1 |   100.00 | Using index |

EDIT This link helped me, it goes now with 8s. https://www.percona.com/blog/2016/10/12/mysql-5-7-performance-tuning-immediately-after-installation/ . But I still find it slow, I just let it in case anybody would know what could also be improved. Thanks

I think removing the subquery might help, along with some more indexes:

SELECT . . . -- you need to fix the `GROUP_CONCAT()` column references
FROM featured doctor LEFT JOIN
     location location
     ON doctor.location_id = location.id LEFT JOIN
     profession profession
     ON doctor.profession_id = profession.id LEFT JOIN 
     featured featured
     ON featured.doctor_id = doctor.doctor_id LEFT JOIN
     user user
     ON featured.user_id = user.id
WHERE doctor.discr = 'doctor' AND
      doctor.state = 'Publié' AND
      featured.discr = 'recommendation'
GROUP BY doctor.uuid;

Then you want an index on featured(discr, state, doctor_id, location_id, profession_id) and featured(doctor_id, discr, user_id) .

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