PostgreSQL - оптимизировать запрос с несколькими подзапросами - PullRequest
0 голосов
/ 07 января 2019

У меня есть 2 таблицы, users и sessions. Таблицы выглядят так:

пользователи - id (int), name (varchar)

сеансов - id (int), user_id (int), ip (inet), cookie_identifier (varchar)

Все столбцы имеют индекс.

Теперь я пытаюсь опросить всех пользователей, у которых есть сеанс с тем же ip или cookie_identifier, что и у конкретного пользователя.

Вот мой запрос:

SELECT *
FROM "users"
WHERE "id" IN
    (SELECT "user_id"
     FROM "sessions"
     WHERE "user_id" <> 1234
       AND ("ip" IN
              (SELECT "ip"
               FROM "sessions"
               WHERE "user_id" = 1234
               GROUP BY "ip")
            OR "cookie_identifier" IN
              (SELECT "cookie_identifier"
               FROM "sessions"
               WHERE "user_id" = 1234
               GROUP BY "cookie_identifier"))
     GROUP BY "user_id")

Таблица users имеет ~ 200 000 строк, таблица sessions имеет ~ 1,5 миллиона строк. Запрос занимает около 3-5 секунд.

Можно ли оптимизировать эти результаты?

1 Ответ

0 голосов
/ 07 января 2019

Я бы предложил в качестве пробной версии удалить все группировки:

SELECT
    *
FROM users
WHERE id IN (
    SELECT
        user_id
    FROM sessions
    WHERE user_id <> 1234
    AND (ip IN (
            SELECT
                ip
            FROM sessions
            WHERE user_id = 1234
            )
        OR cookie_identifier IN (
            SELECT
                cookie_identifier
            FROM sessions
            WHERE user_id = 1234
            )
        )
    )
;

Если это не поможет, попробуйте изменить вышеприведенное, чтобы использовать EXISTS вместо IN

SELECT
    *
FROM users u
WHERE EXISTS (
    SELECT
        NULL
    FROM sessions s
    WHERE s.user_id <> 1234
    AND u.id = s.user_id
    AND EXISTS (
        SELECT
            NULL
        FROM sessions s2
        WHERE s2.user_id = 1234
        AND (s.ip = s2.ip
          OR s.cookie_identifier = s2.cookie_identifier
            )
        )
    )
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...