MySQL GROUP BY проблема с производительностью - PullRequest
4 голосов
/ 22 января 2010

Это запрос, который я выполняю (без некоторых несоответствующих соединений):

SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
GROUP BY a.id

Каждая строка «a» связана от 1 до 5 строк в «b».

Проблема в том, что у GROUP BY есть проблемы с производительностью (при использовании GROUP BY требуется 10 или более раз, чем при отсутствии). Мне нужно получить только одну строку каждого члена в «а».

Как я могу сделать это быстрее?

edit: мне нужно иметь возможность фильтровать по a.id и / или c.id. Набор результатов, который я должен получить, - это только 1 строка на «действительный» член «a», то есть строки, соответствующие ограничениям. Строки, которые не соответствуют фильтрам, возвращаться не должны. В моем исходном запросе это было бы сделано следующим образом:

SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
WHERE c.id = 1
OR a.id = 1
GROUP BY a.id

a.id, b.id_anunciante, b.id_rubro, c.id - все индексы.

Ответы [ 2 ]

5 голосов
/ 22 января 2010
SELECT  a.*,
        (
        SELECT  c.id
        FROM    b
        JOIN    с
        ON      c.id = b.id_rubro
        WHERE   b.id_anunciante = a.id
        -- add the ORDER BY condition to define which row will be selected.
        LIMIT 1
        )
FROM    a

Создайте индекс на b (id_anunciante), чтобы он работал быстрее.

Обновление:

Вам не нужно OUTER JOINs здесь.

Перепишите ваш запрос следующим образом:

SELECT  a.*, c.id
FROM    a
JOIN    b
ON      b.id_anunciante = a.id
JOIN    c
ON      c.id = b.id_rubro
WHERE   a.id = 1
UNION ALL
SELECT  a.*, 1
FROM    a
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    c
        JOIN    b
        ON      b.id_rubro = c.id
        WHERE   c.id = 1
                AND b.id_anunciante = a.id
        )
0 голосов
/ 22 января 2010

Добавьте ORDER BY NULL, чтобы избежать неявной сортировки, выполняемой MySQL при группировании по.

Полагаю, у вас есть индексы / PK для a.id, b.id_anunciante, b.id_rubro и c.id? Я полагаю, вы можете попробовать добавить составной индекс для (b.id_anunciante, b.id_rubro), если ваша версия mysql не может выполнить слияние индекса.

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