SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 28.09.2011 15:42:51

Lacmus
Участник
Зарегистрирован: 28.09.2011
Сообщений: 4

Оптимизация запроса с COUNT

Помогите пожалуйста с оптимизацией запроса...

SELECT
    a.id,
    a.name,
    m.name,
    (SELECT COUNT(*) FROM comment k WHERE k.mid = 31 AND k.pid = a.id) AS count_all,
    (SELECT COUNT(*) FROM comment c WHERE c.mid = 31 AND c.pid = a.id AND c.show = 1) AS count_show,
    u.name
FROM
    tovar a
LEFT JOIN
    proizvoditel m
        ON a.pid = m.id
LEFT JOIN
    users u
        ON a.uid = u.id
WHERE
    a.mid = 31

В данном случае подзапросы с Count очень сильно тормозят, как перестроить запрос без изменения структуры базы?

Отредактированно Lacmus (28.09.2011 15:50:45)

Неактивен

 

#2 28.09.2011 21:21:38

Александр Трофимов
Завсегдатай
Откуда: Юрмала
Зарегистрирован: 19.09.2011
Сообщений: 95

Re: Оптимизация запроса с COUNT

SELECT
    a.id,
    a.name,
    m.name,
    u.name,
    COUNT(c.id) as count_all,
    SUM(c.show) as count_show
FROM
    tovar a
LEFT JOIN
    proizvoditel m
        ON a.pid = m.id
LEFT JOIN
    users u
        ON a.uid = u.id
LEFT JOIN
    comment c ON (a.id = c.pid)
WHERE
    a.mid = 31
GROUP BY a.id, a.pid, a.uid


При условии, что a.mid всегда равен c.mid и при условии, что c.show у тебя всегда 0 или 1.

А почему юзер и производитель подключены через LEFT JOIN? Судя по запросу у товара всегда есть один производитель и один юзер, которому товар принадлежит. Если так, то я бы сделал через просто JOIN.

Неактивен

 

#3 28.09.2011 22:15:51

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Оптимизация запроса с COUNT

Ура, хоть один человек понимает, что левые объединения — зло! smile

EXPLAIN запроса и структура таблиц таки нужна, иначе можно гадать долго.

Неактивен

 

#4 28.09.2011 23:40:01

Lacmus
Участник
Зарегистрирован: 28.09.2011
Сообщений: 4

Re: Оптимизация запроса с COUNT

SELECT
    a.id,
    a.name,
    m.name,
    u.name,
    COUNT(c.id) as count_all,
    SUM(c.show) as count_show
FROM
    tovar a
LEFT JOIN
    proizvoditel m
        ON a.pid = m.id
LEFT JOIN
    users u
        ON a.uid = u.id
LEFT JOIN
    comment c ON (a.id = c.pid)
WHERE
    a.mid = 31
GROUP BY a.id, a.pid, a.uid


Александр Трофимов написал:

При условии, что a.mid всегда равен c.mid и при условии, что c.show у тебя всегда 0 или 1.

a.mid не всегда равен c.mid, c.show 0 или 1

Александр Трофимов написал:

А почему юзер и производитель подключены через LEFT JOIN? Судя по запросу у товара всегда есть один производитель и один юзер, которому товар принадлежит. Если так, то я бы сделал через просто JOIN.

Не всегда у товара присутствует производитель (в базу в этом случае в a.pid заносится 0) и пользователь (в моем случае это id пользователя подтвердившего правильность заполнения формы товара) отсюда и LEFT JOIN


Огромное спасибо за идею COUNT(c.id) as count_all, SUM(c.show) as count_show, как то не подумал о такой возможности, век живи как говорится....

Отредактированно Lacmus (28.09.2011 23:41:21)

Неактивен

 

#5 28.09.2011 23:45:38

Lacmus
Участник
Зарегистрирован: 28.09.2011
Сообщений: 4

Re: Оптимизация запроса с COUNT

paulus написал:

Ура, хоть один человек понимает, что левые объединения — зло! smile

Забавно звучит из уст администратора и гуру, без ссылок и/на обоснования ;D

Отредактированно Lacmus (28.09.2011 23:47:50)

Неактивен

 

#6 29.09.2011 11:57:17

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Оптимизация запроса с COUNT

Хех. Хотите потроллить? Вот вам ссылка на знающего человека:
http://sqlinfo.ru/forum/viewtopic.php?pid=27319#p27319 wink

Обоснования не поленитесь подумать (ну или поискать на форуме, если
думать совсем уже не хочется). Хотя, думать полезнее.

Неактивен

 

#7 29.09.2011 22:38:49

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизация запроса с COUNT

paulus написал:

Хех. Хотите потроллить? Вот вам ссылка на знающего человека:
http://sqlinfo.ru/forum/viewtopic.php?pid=27319#p27319 wink

Обоснования не поленитесь подумать (ну или поискать на форуме, если
думать совсем уже не хочется). Хотя, думать полезнее.

Я не ленюсь думать, на форумах тоже искал, но про злые качества LEFT JOIN-а никогда не слышал. А про зло JOIN-a слышал :-)
Буду рад если подкинете сылочку на материал либо обоснуете вашу теорию.

Неактивен

 

#8 30.09.2011 12:26:24

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Оптимизация запроса с COUNT

omg. Любая лишняя проверка на NULL будет плохой, будучи применяемой
на каждую строку. Когда у нас внутреннее объединение — мы всегда объеди-
няем строки (нет строки — сразу пропускаем). А когда у нас левые объедине-
ния — мы вынуждены даже строки, которых нет в другой таблице хранить в
выборке в виде NULL. В простых случаях MySQL умеет относительно безболез-
ненно сводить левые объединения к внутренним, но для объединения несколь-
ких (3+) таблиц он может это не сделать.

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

Неактивен

 

#9 30.09.2011 14:33:22

Lacmus
Участник
Зарегистрирован: 28.09.2011
Сообщений: 4

Re: Оптимизация запроса с COUNT

paulus написал:

omg. Любая лишняя проверка на NULL будет плохой, будучи применяемой
на каждую строку. Когда у нас внутреннее объединение — мы всегда объеди-
няем строки (нет строки — сразу пропускаем). А когда у нас левые объедине-
ния — мы вынуждены даже строки, которых нет в другой таблице хранить в
выборке в виде NULL. В простых случаях MySQL умеет относительно безболез-
ненно сводить левые объединения к внутренним, но для объединения несколь-
ких (3+) таблиц он может это не сделать.

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

Спасибо за достойное объяснение и троллинг не причем, просто не верю в пустые утверждения, считаю если человек знает он сможет подтвердить то о чем говорит, если только уверен - сошлется в google..

еще раз спасибо

Неактивен

 

#10 01.10.2011 12:37:36

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизация запроса с COUNT

paulus написал:

omg. Любая лишняя проверка на NULL будет плохой, будучи применяемой
на каждую строку. Когда у нас внутреннее объединение — мы всегда объеди-
няем строки (нет строки — сразу пропускаем). А когда у нас левые объедине-
ния — мы вынуждены даже строки, которых нет в другой таблице хранить в
выборке в виде NULL.

В этом случае я с вами полностью согласен. Но он никак не связан с запросом сверху.

paulus написал:

В простых случаях MySQL умеет относительно безболез-
ненно сводить левые объединения к внутренним, но для объединения несколь-
ких (3+) таблиц он может это не сделать.

Вот совсем непонятно ...  что зачет "сводить левые объединения к внутренним" ?
Опять же уточню в двух таблицах есть одинаковое количество общих записей.
Если я правильно понимаю, при использовании JOIN-а, Mysql автоматически выбирает кто из двух таблиц будет основной а кто дополнительной и осуществляет физически обычный LEFT JOIN.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson