2016-05-22 2 views
1

Я изучаю это в течение нескольких часов, и лучший код, который я придумал, - это пример, который я нашел в overstack. Я прошел через несколько дериваций, но следующий - единственный запрос, который возвращает правильные данные, проблема в том, что он берет 139 (более 2 минут), чтобы возвращать только 30 строк данных. Я застрял. (Life_p является «любит»mysql Несколько левых объединений с использованием count

SELECT 
    logos.id, 
    logos.in_gallery, 
    logos.active, 
    logos.pubpriv, 
    logos.logo_name, 
    logos.logo_image, 
    coalesce(cc.Count, 0) as CommentCount, 
    coalesce(lc.Count, 0) as LikeCount 
FROM logos 

left outer join(
    select comments.logo_id, count(*) as Count from comments group by comments.logo_id 
) cc on cc.logo_id = logos.id 

left outer join(
    select life_p.logo_id, count(*) as Count from life_p group by life_p.logo_id 
) lc on lc.logo_id = logos.id 

WHERE logos.active = '1' 
    AND logos.pubpriv = '0' 
GROUP BY logos.id 
ORDER BY logos.in_gallery desc 
LIMIT 0, 30 

Я не уверен, что случилось, если я делаю их по отдельности meaningremove в coalece и один из объединений:.

SELECT 
    logos.id, 
    logos.in_gallery, 
    logos.active, 
    logos.pubpriv, 
    logos.logo_name, 
    logos.logo_image, 
    count(*) as lc 
FROM logos 

left join life_p on life_p.logo_id = logos.id 

WHERE logos.active = '1' 
    AND logos.pubpriv = '0' 
GROUP BY logos.id 
ORDER BY logos.in_gallery desc 
LIMIT 0, 30 

, который работает меньше, чем половина сек (2-300 мс) ....

Вот ссылка на объяснения: https://logopond.com/img/explain.png

+0

overstack я имею в виду здесь 'stackoverflow': D, Thanks Jorge Мне было интересно, как исправить отображение кода –

+0

Pls добавляет результат объяснения и PLS также перечисляет индексы на 3 затронутых таблицах! – Shadow

+0

Комментарии.logo_id, life_p.logo_id и логотипы.id индексируются по их соответствующим таблицам. Таблица комментариев и логотипов содержит несколько столбцов, а некоторые из них индексируются, но не связаны с запросом в таблице. heres ссылка на объяснение https://logopond.com/img/explain.png –

ответ

1

Вы можете создать несколько индексов соединяемых полей:

ALTER TABLE ADD INDEX tableidx__tableName__fieldName (field)

В вашем случае будет что-то вроде:

ALTER TABLE ADD INDEX куб.см idx__cc__logo_id (logo_id);

+0

Я попробую это, не думаю, что это было необходимо, поскольку столбцы, на которые он ссылался, были проиндексированы, но, очевидно, его сейчас не тянет эффективно. Я дам вам знать, если это работает –

+0

no go on this, индекс уже находится в соответствующей таблице, и добавление этого только дублирует индекс, который уже существует. –

2

У MySQL есть своеобразная причуда, которая допускает предложение group by, которое не перечисляет все неагрегационные столбцы. Это нехорошо, и вы должны всегда указывать ВСЕ неагрегационные столбцы в предложении group by.

Обратите внимание, что при подсчете объединенных таблиц полезно знать, что функция COUNT() игнорирует NULL, поэтому для LEFT JOIN, где возможны NULL, не используйте COUNT (*), вместо этого используйте столбец изнутри объединенная таблица, и будут подсчитываться только строки из этой таблицы. Из этих пунктов я бы предложил следующую структуру запросов.

SELECT 
     logos.id 
     , logos.in_gallery 
     , logos.active 
     , logos.pubpriv 
     , logos.logo_name 
     , logos.logo_image 
     , COALESCE(COUNT(cc.logo_id), 0) AS CommentCount 
     , COALESCE(COUNT(lc.logo_id), 0) AS LikeCount 
FROM logos 
     LEFT OUTER JOIN comments cc ON cc.logo_id = logos.id 
     LEFT OUTER JOIN life_p lc ON lc.logo_id = logos.id 
WHERE logos.active = '1' 
AND logos.pubpriv = '0' 
GROUP BY 
     logos.id 
     , logos.in_gallery 
     , logos.active 
     , logos.pubpriv 
     , logos.logo_name 
     , logos.logo_image 
ORDER BY logos.in_gallery DESC 
LIMIT 0, 30 

Если у вас по-прежнему возникают проблемы с производительностью, используйте план выполнения и рассмотрите возможность добавления индексов.

+0

это ближе к тому, что у меня было, когда я начал с точки зрения левого объединения, но у меня не было коалесценции и всех групповых байтов, проблема с этим - это (занимает меньше времени 30 секунд) делает столбец вроде и комментариев то же число, я постараюсь запустить его с четкими, но я тоже не повезло. В конечном счете, я просто пытаюсь избежать выполнения запроса в цикле for, когда я прохожу, чтобы получить информацию о логотипе и другие необходимые данные из других таблиц. –

+0

'select distinct' ничего не достигнет при использовании в этом запросе (group by производит различные строки уже). Подсчеты будут только такими же, если в каждой объединенной таблице на группу должно быть одинаковое количество строк. –

+0

Да, я просто запросил запрос к базе данных и дал точно такую ​​же информацию как в счетчике комментариев, так и в столбцах count. Я имел в виду пробег в комментариях count и count life_p –

0

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

SELECT 
    logos.id, 
    logos.in_gallery, 
    logos.active, 
    logos.pubpriv, 
    logos.logo_name, 
    logos.logo_image, 
(Select COUNT(comments.logo_id) FROM comments 
    WHERE comments.logo_id = logos.id) AS coms, 
(Select COUNT(life_p.logo_id) FROM life_p 
    WHERE life_p.logo_id = logos.id) AS floats 

FROM logos 
WHERE logos.active = '1' AND logos.pubpriv = '0' 
ORDER BY logos.in_gallery desc 
LIMIT ". $start .",". $pageSize ." 
+0

вам нужно предложение group by в этом запросе? поскольку теперь вы используете 'коррелированные подзапросы', по-видимому, нет никаких причин для группы по –

+0

Хм, вы правы, удаляете, спасибо! –

+0

EDIT удалил группу, поскольку в этом подходе нет необходимости –

0

Также вы можете создать таблицы отображения, чтобы ускорить попытку запроса:

CREATE TABLE mapping_comments AS 
SELECT 
    comments.logo_id, 
    count(*) AS Count 
FROM 
    comments 
GROUP BY 
    comments.logo_id 
) cc ON cc.logo_id = logos.id 

Затем изменить код

left outer join(

должен стать

inner join mapping_comments as mp on mp.logo_id =cc.id 

Тогда каждый добавляется новый комментарий к th таблицу e cc вам нужно обновить таблицу сопоставления или вы можете создать хранимую процедуру, чтобы сделать это автоматически, когда ваша таблица cc изменится

 Смежные вопросы

  • Нет связанных вопросов^_^