Задавайте вопросы, мы ответим
Вы не зашли.
Помогите с, возможно, простым запросом.
Есть таблица получателей Email-рассылки
Неактивен
select email, sum(if(`status`='success',1,0)) c from er group by 1 having c=0; -- выбрать всех пользователей, у которых все рассылки были отправлены с ошибкой.
(select count(*) from er where `stutus` = 'error')*100/(select count(*) from er); -- какой процент из всех отправок был отправлен с ошибкой.
Неактивен
Спасибо! Работает.
Только в моей таблице на 800 000 записей запросы выполняется около 15 сек.
Можно его как-то оптимизировать, ускорить?
Поможет ли индекс на поле status, если есть общий индекс на поля id_emailing и status?
Есть ли еще какие-то варианты?
Еще вопрос. А что дает
Отредактированно Meshok (20.06.2013 13:33:31)
Неактивен
Meshok написал:
Можно его как-то оптимизировать, ускорить?
попробуйте для первого запроса индекс на `email`, а для второго на `status`
Meshok написал:
Поможет ли индекс на поле status, если есть общий индекс на поля id_emailing и status?
FAQ №5
Meshok написал:
Есть ли еще какие-то варианты?
можно попробовать переписать первый запрос в виде
select er.email from er left join
(select email from er where `status`='success' group by 1) using(email) where t.email is null;
или
select email from er group by 1 having max(status)='error'; -- если вы уверены, что после рассылки не могут остаться записи со статус wait, то данный вариант оптимален при наличии индекса на (email,status). Правильно работать будет после осуществления рассылки, когда нет статуса wait (или можно изменить значение статуса с success на z_success.)
Meshok написал:
Еще вопрос. А что дает
group by 1?
Это аналог group by `email`, чтобы меньше писать.
Неактивен
Теперь проблема, если я использую
Отредактированно Meshok (20.06.2013 18:21:32)
Неактивен
Meshok написал:
Теперь проблема, если я использую
select email from er group by 1 having max(status)='error', то все отлично работает и используются индекты и запрос быстро выполняется, а если я делаю такselect * from er group by email having max(status)='error', то индексы перестают использоваться
В первом случае запрос выполняется используя данные только индекса. Во втором случае требуется ещё обращение к данным таблицы. Проще последовательно перебрать всю таблицу, чем каждый раз туда сюда перемещать головку диска в случае использования индекса.
Зачем вы выбираете все поля таблицы?
Meshok написал:
А вообще мне нужно еще и JOIN'ы в этот запрос добавлять.
Зачем? Этот запрос дает вам список email тех пользователей, у которых все рассылки были отправлены с ошибкой.
Meshok написал:
Индаксы создал для (email), (status) и (email, status) в первом случае используется (email, status).
При наличии (email, status) индекс на (email) лишний.
Неактивен
Мне нужно создать таблицу статистики с емейлами, именем, аватаркой пользователя, которому принадлежит емейл. Это минимум, что нужно. Остальное не критично, хотя еще есть такие потребности, как знать как был подписан пользователь (с помощью регисрации на сайте или через форму подписки) и т.п.
Индексы я создал на всякий случай разные, чтобы понимать какой будет использоваться. Тем более я пробовал и другие запросы, описанные Вами выше.
Неактивен