За последние 24 часа нас посетили 21927 программистов и 988 роботов. Сейчас ищут 662 программиста ...

Оптимизировать MySQL запрос?

Тема в разделе "MySQL", создана пользователем ArtmirArt, 22 апр 2019.

Метки:
  1. ArtmirArt

    ArtmirArt Новичок

    С нами с:
    22 апр 2019
    Сообщения:
    2
    Симпатии:
    0
    Здравствуйте. Как можно оптимизировать такой MySQL-запрос?

    Код (Text):
    1.  
    2. SELECT U.id,U.name,U.birthday,U.sex,U.city,U.status,U.regdate
    3. FROM users U
    4. LEFT JOIN shipping SA ON SA.user_id=U.id
    5. LEFT JOIN activity A ON A.user_id=U.id
    6. LEFT JOIN blocked B ON B.user_id=U.id
    7. LEFT JOIN deleted D ON D.user_id=U.id
    8. WHERE SA.id and A.last_activity_at > 1553260577 and B.id is NULL and D.id is NULL and
    9. U.id NOT IN (
    10. ( SELECT who_id FROM blacklist WHERE user_id=17 )
    11. UNION
    12. ( SELECT user_id FROM blacklist WHERE who_id=17 )
    13. UNION
    14. ( SELECT 17 )
    15. )
    16. GROUP BY U.id ORDER BY U.id DESC LIMIT 1 OFFSET 3
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    1. разумная денормализация: создать логическое поле inactive в users, которое будет 1 в случае попадания пользователя в blocked или deleted. в таком случае можно избавиться от двух джойнов.

    2. я так понимаю blacklist это персональный черный список: если я не хочу дружить с Петей или Петя не хочет дружить со мной. такие вещи можно кешировать для текущего пользователя и подставлять в запрос готовый список айдишников как NOT IN (готовый_список_ids_как_параметр)

    таким образом запрос будет без джойнов и подзапросов вообще.

    group by u.id мне кажется здесь просто лишний. да и ошибка это при строгом ansi sql.

    limit 1 без сортировки, это точно ???
     
  3. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    PHP:
    1. SELECT
    2.     U.id, U.name, U.birthday, U.sex, U.city, U.status, U.regdate
    3. FROM users U
    4. INNER JOIN shipping SA ON SA.user_id=U.id
    5. INNER JOIN activity A ON A.user_id=U.id
    6. LEFT JOIN blocked B ON B.user_id=U.id
    7. LEFT JOIN deleted D ON D.user_id=U.id
    8. WHERE A.last_activity_at > 1553260577
    9.     and B.id is NULL
    10.     and D.id is NULL
    11.     AND U.id NOT IN (
    12.         SELECT IF(user_id=17, who_id, IF(who_id=17, user_id, 0)) FROM blacklist WHERE user_id=17 OR who_id=17
    13.         UNION SELECT 17
    14.     )
    15. ORDER BY U.id DESC
    16. LIMIT 1 OFFSET 3;
    Если миллионы записей в Blacklist, то вместо NOT IN() можно попробовать выборку нужных ИД во временную таблицу, и потом джойн с ней.