Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / как оптимизировать запрос, если в таблицах по 100 000+ записей / 21 сообщений из 21, страница 1 из 1
20.10.2016, 16:02
    #39330820
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
как оптимизировать этот запрос когда в обоих таблицах по 100 000+ записей

select count(*) FROM user WHERE `user`.`email` !="" AND `user`.`last_login` <= "2016-08-01 00:00:00" AND (`user`.`banned` = 0 OR `user`.`banned` is NULL) AND NOT EXISTS (SELECT 1 FROM `notify_user` WHERE (`notify_user`.user_id = `user`.`id` OR `notify_user`.email = `user`.`email`) AND (`notify_user`.`event`=103 OR `notify_user`.`event`=105)) AND user.email != '' GROUP BY user.email ORDER BY user.id ASC

сейчас выполняется по часу или даже больше
...
Рейтинг: 0 / 0
20.10.2016, 17:16
    #39330901
trew
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshed,

Сколько записей возвращают запросы
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select count(*) 
FROM user 
WHERE `user`.`last_login` <= "2016-08-01 00:00:00" 


select count(*) 
FROM user 
WHERE (`user`.`banned` = 0 OR `user`.`banned` is NULL) 



На поле last_login и banned индексы есть?

Можно получить предварительную выборку, ниже. Она быстро формируется?

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT  `user`.`id`, `user`.`email` 
FROM user 
WHERE `user`.`last_login` <= "2016-08-01 00:00:00" 
AND NOT EXISTS (
SELECT 1 FROM `notify_user` 
WHERE `notify_user`.user_id = `user`.`id`
)



Какие индексы на таблицах пока не известно.
...
Рейтинг: 0 / 0
20.10.2016, 17:25
    #39330914
Fitter2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Еще можно попробовать заменить AND NOT EXISTS на LEFT JOIN и искать/считать NULL с правой части запроса.
И еще ко всем заметкам от trew Я бы добавил EXPLAIN.
Этот запрос должен отрабатывать за 3 минуты максимум. (личный опыт на 650к строк)
...
Рейтинг: 0 / 0
20.10.2016, 17:34
    #39330928
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
trewkhurshed,

Сколько записей возвращают запросы
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select count(*) 
FROM user 
WHERE `user`.`last_login` <= "2016-08-01 00:00:00" 


select count(*) 
FROM user 
WHERE (`user`.`banned` = 0 OR `user`.`banned` is NULL) 



На поле last_login и banned индексы есть?

Можно получить предварительную выборку, ниже. Она быстро формируется?

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT  `user`.`id`, `user`.`email` 
FROM user 
WHERE `user`.`last_login` <= "2016-08-01 00:00:00" 
AND NOT EXISTS (
SELECT 1 FROM `notify_user` 
WHERE `notify_user`.user_id = `user`.`id`
)



Какие индексы на таблицах пока не известно.

1. По первому запросу 99970
2. По второму 113217
3. Индекс был только у banned last_login добавил
4. Да сформировалось быстро
5. В таблице notify_user почти не было индексов добавил по нужным полям
...
Рейтинг: 0 / 0
20.10.2016, 17:42
    #39330933
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Fitter2Еще можно попробовать заменить AND NOT EXISTS на LEFT JOIN и искать/считать NULL с правой части запроса.
И еще ко всем заметкам от trew Я бы добавил EXPLAIN.
Этот запрос должен отрабатывать за 3 минуты максимум. (личный опыт на 650к строк)

Код: plsql
1.
select count(*) FROM user LEFT JOIN notify_user on notify_user.user_id = user.id WHERE `user`.`email` !="" AND `user`.`last_login` <= "2016-08-01 00:00:00" AND (`user`.`banned` = 0 OR `user`.`banned` is NULL)  AND (`notify_user`.user_id = `user`.`id` OR `notify_user`.email = `user`.`email`) AND (`notify_user`.`event`=103 OR `notify_user`.`event`=105)) AND user.email != '' GROUP BY user.email ORDER BY user.id ASC

так что ли?
...
Рейтинг: 0 / 0
20.10.2016, 18:39
    #39330980
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT  `user`.`id`, `user`.`email` 
FROM user 
WHERE `user`.`last_login` <= "2016-08-01 00:00:00" 
AND NOT EXISTS (
SELECT 1 FROM `notify_user` 
WHERE `notify_user`.user_id = `user`.`id`  OR `notify_user`.email = `user`.`email`
)

это уже занимает больше времени
...
Рейтинг: 0 / 0
20.10.2016, 19:53
    #39331038
Fitter2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Чтоб мне не расписывать вашу колбасу, опишу идею:
LEFT JOIN если посмотреть теоритически должен дать вам
user.idnotify_user.user_id22NULL231725NULL

получается, что вам нужно подсчитать все NULL, типа
SELECT SUM(IF(notify_user.user_id, 0, 1) FROM .... - думаю это будет быстрее.

Хотя я не понял после вашего ответа, может индексы решили вашу проблему.
Вы хоть результаты свои публикуйте, мне вот интересны результаты.
...
Рейтинг: 0 / 0
21.10.2016, 06:10
    #39331156
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Fitter2, все идею понял теперь. но он по дублям криво подбирает

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT user.id, user.email, notify_user.user_id, notify_user.email AS notify_email
FROM user
LEFT JOIN notify_user ON notify_user.user_id = user.id
WHERE `user`.`last_login` <= "2016-08-01 00:00:00"
AND (
`user`.`banned` =0
OR `user`.`banned` IS NULL
)
AND `notify_user`.`email` IS NULL
AND user.email != ''
GROUP BY user.email
ORDER BY `user`.`id`  ASC



один email он брал и уже существует в таблице notify_user .
Делаю вторую выборку туда уже попадает другой пользователь с таким email-ом
...
Рейтинг: 0 / 0
21.10.2016, 09:20
    #39331206
paver
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshed,

а объясните чайнику, для чего у вас конструкция GROUP BY?
...
Рейтинг: 0 / 0
21.10.2016, 09:27
    #39331210
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshedкак оптимизировать этот запрос когда в обоих таблицах по 100 000+ записей

select count(*) FROM user WHERE `user`.`email` !="" AND `user`.`last_login` <= "2016-08-01 00:00:00" AND (`user`.`banned` = 0 OR `user`.`banned` is NULL) AND NOT EXISTS (SELECT 1 FROM `notify_user` WHERE (`notify_user`.user_id = `user`.`id` OR `notify_user`.email = `user`.`email`) AND (`notify_user`.`event`=103 OR `notify_user`.`event`=105)) AND user.email != '' GROUP BY user.email ORDER BY user.id ASC

сейчас выполняется по часу или даже больше


создать нужные индексы.

запрос надо немного переделать - or вынести из подзапроса, и использовать два подзапроса без or. Снаружи позволяла они будут объединяться уже по AND.

индексы в notify user нужно два по (event,user ID ) и по (event,email)

в user по last logon.
...
Рейтинг: 0 / 0
21.10.2016, 09:28
    #39331211
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
paverkhurshed,

а объясните чайнику, для чего у вас конструкция GROUP BY?
кстати, да...
...
Рейтинг: 0 / 0
21.10.2016, 09:30
    #39331214
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshed,
вообще, когда у автора запросе в голове каша, то такие вот неработающие запросы и получается.

автор, попробуй вообще добиться того, чтобы у тебя не было ни одного OR в запросе.

для этого придется менять базу данных и приложение....
...
Рейтинг: 0 / 0
21.10.2016, 11:30
    #39331346
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
MasterZiv, получилось так, что в таблице юзеров появились несколько юзеров с одинаковыми email, отсюда и group by, чтобы повторно не отправлять некое письмо, надеюсь понятно объяснил.
...
Рейтинг: 0 / 0
21.10.2016, 12:29
    #39331447
paver
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshedв таблице юзеров появились несколько юзеров с одинаковыми email, отсюда и group by, чтобы повторно не отправлять некое письмо
Несколько разных юзеров или дубли?
Если разные, кому именно нужно/не нужно отправлять?

Вот это вот и есть каша
...
Рейтинг: 0 / 0
21.10.2016, 13:02
    #39331482
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
paver, разные юзеры, данные разные кроме email.
Надо перым email -ом в таких случаях надо отправить.
Да не спорю, просто не учли один момент и получилось пользователи с одинаковым email , их от силы наберется 150 из 120000
Но все же надо исключать повторную отправку
...
Рейтинг: 0 / 0
21.10.2016, 14:59
    #39331637
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Таблица user


Таблице notify_user


Надо сделать выборку из user. которых нет в таблице notify_user по user_id и по email, для примера добавил одинаковые email, их надо исключить
...
Рейтинг: 0 / 0
21.10.2016, 15:37
    #39331695
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
khurshedMasterZiv, получилось так, что в таблице юзеров появились несколько юзеров с одинаковыми email, отсюда и group by, чтобы повторно не отправлять некое письмо, надеюсь понятно объяснил.

DISTINCT
...
Рейтинг: 0 / 0
21.10.2016, 16:19
    #39331754
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Вот так выполняется за 10 секунд
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SELECT id, email
FROM user
WHERE `user`.`email` != ""
AND user.last_login <= '2016-08-01'
AND NOT
EXISTS (

SELECT 1
FROM `notify_user`
WHERE `notify_user`.`user_id` = `user`.`id`
AND (
`notify_user`.`event` =103
OR `notify_user`.`event` =105
)
)
AND NOT
EXISTS (

SELECT 1
FROM `notify_user`
WHERE `notify_user`.email = `user`.`email`
AND (
`notify_user`.`event` =103
OR `notify_user`.`event` =105
)
)
GROUP BY user.email
ORDER BY user.id ASC
...
Рейтинг: 0 / 0
21.10.2016, 17:28
    #39331828
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
MasterZivkhurshedMasterZiv, получилось так, что в таблице юзеров появились несколько юзеров с одинаковыми email, отсюда и group by, чтобы повторно не отправлять некое письмо, надеюсь понятно объяснил.

DISTINCT
Так ведь это опять может вызвать сортировку.

Так что лучше всего провести мероприятия по блокировке таких пользователей по выдуманным поводам.
...
Рейтинг: 0 / 0
24.10.2016, 23:58
    #39333191
Fitter2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Прочитав ваши посты запутался, мне казалось вы что-то хотели подсчитать, а по последним постам вижу вы там выборку берете.
Всегда лучше проговаривать о том что вы имеете и что хотите получить.
В любом случае 1 час и 10 сек - прогресс заметен :)
...
Рейтинг: 0 / 0
27.10.2016, 06:13
    #39334910
khurshed
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как оптимизировать запрос, если в таблицах по 100 000+ записей
Fitter2, ну выборку делаю после того как делаю расчет количества
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / как оптимизировать запрос, если в таблицах по 100 000+ записей / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]