Можно ли оптимизировать запрос?

Ссылка скопирована
1 ответ

Мне нужно получить данные чатов для пользователя и к этим данными добавить колонку с именем другого пользователя этого чата.

У меня получился такой запрос. Он работает, но, меня смущает дубликаты запросов и его многоуровневость.

select c.*, name from chats c          left join (             select concat(u.first_name, ' ', u.last_name) as name, cp.chat_id             from users u             left join chat_participants ip on u.id = ip.user_id             where ip.user_id != 1 and ip.chat_id in (                 select cp.chat_id                 from chat_participants cp                 where cp.user_id = 1 and cp.is_deleted = false -- duplicate             )         ) p on p.chat_id = c.id where c.id in(     select cp.chat_id     from chat_participants cp     where cp.user_id = 1 and cp.is_deleted = false -- duplicate );

select c.*, name from chats c left join ( select concat(u.first_name, ' ', u.last_name) as name, cp.chat_id from users u left join chat_participants ip on u.id = ip.user_id where ip.user_id != 1 and ip.chat_id in ( select cp.chat_id from chat_participants cp where cp.user_id = 1 and cp.is_deleted = false -- duplicate ) ) p on p.chat_id = c.id where c.id in( select cp.chat_id from chat_participants cp where cp.user_id = 1 and cp.is_deleted = false -- duplicate );

Можно ли его оптимизировать? И как это сделать?

Таблицы
chats

Можно ли оптимизировать запрос?

chat_participants

Можно ли оптимизировать запрос?

users

Можно ли оптимизировать запрос?

Explain

Можно ли оптимизировать запрос?

Дополнительно:

explain сделайте

  • Дмитрий, Добавил
  • Yevhenii K, а другой пользователь это какой? Просто первый пользователь из чата в котором участвовал пользователь?
  • Дмитрий, В чате с id = 1 состоит 2 пользователя, 1 и 3. Когда я делаю выборку чатов для 1, нужно что бы возле чата с id = 1 было имя пользователя 3.
  • Yevhenii K, ну просто если в чате будет еще один пользователь с id 4 - чат выведется два раза, с пользователем 3 и 4.
    Ну на вскидку как то так.
    select        chats.*,         others.first_name,         others.last_name from chats inner join chat_participants on chat_participants.chart_id = chats.id and chat_participants.user_id = 1 and chat_participants.is_deleted = false left join chat_participants as other_participants on other_participants.chart_id = chats.id and other_participants.user_id != 1 and other_participants.is_deleted = false left join users as others on others.id = other_participants.user_id;

    select chats.*, others.first_name, others.last_name from chats inner join chat_participants on chat_participants.chart_id = chats.id and chat_participants.user_id = 1 and chat_participants.is_deleted = false left join chat_participants as other_participants on other_participants.chart_id = chats.id and other_participants.user_id != 1 and other_participants.is_deleted = false left join users as others on others.id = other_participants.user_id;

    если понял правильно - то можно попробовать сравнить explain

  • Дмитрий, Это для чата 1х1. Спасибо, ваш запрос чуть быстрее.
  • Ответы:

    Можно использовать inline views (или еще называют common table expressions)

    with cp_view as (  select cp.chat_id  from chat_participants cp  where cp.user_id = 1 and cp.is_deleted = false) .....

    with cp_view as ( select cp.chat_id from chat_participants cp where cp.user_id = 1 and cp.is_deleted = false) .....

    • cost увеличился на ~40%
    • Yevhenii K, покажи как сделал
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Дмитрий К. Ответ

    Да, конечно, можно оптимизировать запрос. Существует несколько способов улучшить производительность запроса к базе данных.

    1. Используйте индексы. Индексы помогают базе данных быстрее находить нужные записи. Убедитесь, что у всех колонок, по которым часто выполняются запросы, созданы индексы.

    ```php

    CREATE INDEX index_name ON table_name (column_name);

    CREATE INDEX index_name ON table_name (column_name);

    ```

    2. Оптимизируйте запросы. Проверьте ваш SQL запрос на наличие лишних JOIN'ов, WHERE условий и сортировок. Иногда можно переписать запрос так, чтобы он выполнялся быстрее.

    3. Используйте хранимые процедуры. Хранимые процедуры могут ускорить выполнение запросов, так как они кешируются и не нужно каждый раз компилировать SQL запрос.

    ```php

    CREATE PROCEDURE procedure_name
    AS
    BEGIN
        -- Your SQL statements here
    END

    CREATE PROCEDURE procedure_name AS BEGIN -- Your SQL statements here END

    ```

    4. Ограничьте количество возвращаемых записей. Если вам не нужны все записи из таблицы, используйте операторы LIMIT или TOP, чтобы ограничить количество возвращаемых строк.

    ```php

    SELECT * FROM table_name LIMIT 10;

    SELECT * FROM table_name LIMIT 10;

    ```

    5. Используйте кэширование. Если данные не часто изменяются, можно использовать кэширование результатов запросов, чтобы не выполнять их каждый раз заново.

    6. Оптимизируйте структуру базы данных. Иногда изменение структуры таблицы (например, нормализация данных) может улучшить производительность запросов.

    Следуя этим рекомендациям, вы сможете значительно улучшить производительность запросов к базе данных.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно