powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите пожалуйста оптимизировать запрос!
21 сообщений из 21, страница 1 из 1
Помогите пожалуйста оптимизировать запрос!
    #39966751
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, я с sql знаком плохо,написал вот такой запрос в базу данных, но он выполняется ооочень долго и выполнить 2-3 таких запроса - проблема.
Смысл в чём - есть посетители которые оставляют свои дни рождения. Таблица имеет несколько колонок (дату посещения и ид посетителя) в ней надо выбрать посетителей, дата посещения которых не дальше чем за 2 года потом по ид посетителя ищем в другой таблице его дату рождения, имя, телефон,город и т.д. ГДЕ дата рождения находится (либо между числами больше сегодняшнего на 11 и 9 дней, либо которое через 10 дней (формулировка разная смысл один,не знаю как правильно это сделать в sql)) ну а так же у которых значение `birthday_tel_bot_chat_id` не пустое. В этих таблицах на данный момент больше 700 000 записей и будет ещё больше. В этом и проблема. Не знаю как правильно оптимизировать. Вот запрос.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT `wvh`.`visitor_id`,`wvs`.`title`, `wvi`.`full_name`,`wvi`.`birth`,`wvi`.`email`,`wvi`.`telephone`,`wvi`.`city`, `wvh`.`date`,`wvs`.`birthday_tel_bot_chat_id`
FROM `wifi_visitors_history`as `wvh` 
LEFT JOIN `wifi_visitors_info` as `wvi` on `wvi`.`visitor_id` = `wvh`.`visitor_id`
LEFT JOIN `wifi_visitors_shop` as `wvs` on `wvh`.`shop_id` = `wvs`.`shop_id`
WHERE `wvi`.`birth` IS NOT NULL
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') < date_format('2020-06-17','%m-%d')
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') > date_format('2020-06-15','%m-%d')
AND `wvh`.`date` > unix_timestamp(180602) 
AND `wvh`.`date` = (SELECT max(`wvh2`.`date`) 
FROM `wifi_visitors_history` as `wvh2` 
where `wvh`.`visitor_id` = `wvh2`.`visitor_id`)
AND `wvs`.`birthday_tel_bot_chat_id` != ''"
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39966933
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
11332266,
А индексы у вас созданы для полей, по которым выборка идёт?
Вы дайте структуру таблиц. И что надо получить на выходе. А по вашему монструозному запросу понять что-то сложно, разве что он
весьма, скажем дипломатично, странный.
Код: sql
1.
2.
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') < date_format('2020-06-17','%m-%d')
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') > date_format('2020-06-15','%m-%d')

Например, почему вот здесь вы не используете простое равенство?
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39966939
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще дичь какая-то!

1. две даты > и < переделать в BETWEEN
2. нужен индекс на поле `wvh2`.`date`
3. нужен индекс на поле `wvh`.`date`
4. нужен индекс на поле `wvi`.`birth`
5. Не уверен что индекс на `wvi`.`birth` будет реализован после работы с полем функций FROM_UNIXTIME и DATE_FORMAT, но если что можно EXPLAIN'ом поглядеть.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39966943
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kormot
1. две даты > и < переделать в BETWEEN
Я так понял, что ему BETWEEN не нужен. Ему надо просто взять текущую дату, сделать + INTERVAL 10 DAY и сравнить получившееся значение с wvi.birth.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39966956
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluck99 - ну это я так понял из запроса просто частный случай, может могут быть произвольные интервалы.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967309
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99, Спасибо за ответ! Равенство не получится использовать потому что надо выбирать за 2 дня например за 8 и 9. Ну вы поняли. А потом я разделяю это дело в коде.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967319
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
есть таблица visitors_history - суда сохраняется каждое посещение(один визитор
может посещать много раз и каждый раз будет новая запись) - из неё надо брать именно последнее посещение каждого пользователя
visitor_iddateshop_id114359123591214360258621314363525222314363515222314362525224

ещё одна таблица visitors_info - там находится информация о посетителях. И надо оставлять только тех, у которых день рождения через 9 и 10 дней. либо если невозможно взять 2 дня то только через 10.
visitor_idfull_namebirth1Вася пупкин8667089412Мария Деб8666225413Иван Иван865153741


и 3 таблица visitors_shop - там данные о заведениях в которые приходят эти посетители. Надо из всей выборки отсеивать тех посетителей которые пришли в заведение у которого telegram_id не пустое и не равно NULL
shop_idtitletelegram_id1kyk123452zavedenie543213testZavedenieNULL4BarBar
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967517
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
11332266
И надо оставлять только тех, у которых день рождения через 9 и 10 дней. либо если невозможно взять 2 дня то только через 10.
Надо из всей выборки отсеивать тех посетителей которые пришли в заведение у которого telegram_id не пустое и не равно NULL
1. С датами так ничего и непонятно. У человека не может быть ДР через 9 или 10 дней одновременно. Либо через 9, либо через 10.
Я так понимаю, вам надо следующее. Например, сегодня 1 июня. Вам надо взять всех, у кого ДР 10-го июня и 11 июня. Завтра, 2-го июня, вам надо взять всех, у кого ДР 11-го июня и 12-го июня. Правильно?
2. Чем отличаются telegram_id = NULL и telegram_id = '' ? С вероятностью 99% я предполагаю, что вам достаточно использовать только одно значение.

Любой сложный запрос можно представить как набор более простых запросов. У вас здесь 3 запроса образуют конечную выборку. Напишите эти три запроса, а потом соедините вместе.
Запрос 1: Выборка MAX(date) из visitors_history с GROUP BY visitor_id
Запрос 2: Выборка из visitors_info где birth = birth + INTERVAL 9 DAY и birth = birth + INTERVAL 10 DAY
Запрос 3: Выборка из visitors_shop где telegram_id IS NULL

Кстати, а что у вас вообще за сервер?
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967600
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,

1 - да. Нужно выбрать всех людей у которых др либо через 10 дней либо через 9
То есть если у Васи др 19 июня, у Виктории 10 июня, у Дмитрия 18 июня при условии что сегодня 9 июня выбрать надо Васю и Дмитрия.
2 - Разница есть - в таблице присутствуют и null значения и "" значения этой строки. Если отрицать только чтото одно - второе выбирается. Поэтому отрицать надо оба значения.
3 - нужно сделать как то это всё одним запросом. Единым. То есть оптимизировать тот запрос который я написал выше но я не знаю как, поэтому и обратился сюда
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967602
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kormot,

Я не понимаю о чём вы, пришлите пожалуйста примерно как вы видите этот запрос
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967667
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
11332266
есть таблица visitors_history - суда сохраняется каждое посещение(один визитор может посещать много раз и каждый раз будет новая запись) - из неё надо брать именно последнее посещение каждого пользователя
visitor_iddateshop_id114359123591214360258621314363525222314363515222314362525224

Брать одно последнее или последнее по каждому шопу?
Если только одно, но оно относится к шопу без телеграма, то клиент в пролете?
Зачем вам левые джойны?
Отличаются ли логически пустые и нулевые телеграмы? Если нет, имеется ли возможность проапдейтить таблицу и привести к единообразию?
Какой у вас сервер?
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967688
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
paver,
1 последнее по каждому шопу. Если визитор ходил в 2 магазина , то я должен это знать
2 да, в пролёте.
3. Не понимаю о чём вы, какие левые?
4. Да, можно привести к одному значению
5. Не знаю, Денвер наверное
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967691
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
AND `wvh`.`date` = (SELECT max(`wvh2`.`date`) 
FROM `wifi_visitors_history` as `wvh2` 
where `wvh`.`visitor_id` = `wvh2`.`visitor_id`)


Вангую, что всё ломается об это и ты получаешь по запросу на каждую запись. Вытащи это в подзапрос и сделай join со всем остальным.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967692
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') < date_format('2020-06-17','%m-%d')
AND date_format(from_unixtime(`wvi`.`birth`),'%m-%d') > date_format('2020-06-15','%m-%d')


Зачем делать форматирование даты, если можно просто сравнить таймштампы?
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967747
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
11332266
paver,
1 последнее по каждому шопу. Если визитор ходил в 2 магазина , то я должен это знать
2 да, в пролёте.
3. Не понимаю о чём вы, какие левые?
4. Да, можно привести к одному значению
5. Не знаю, Денвер наверное

1. Тогда группировка по 2 id-полям, получение максимальной даты по группировке.
(SELECT visitor_id, shop_id, MAX(date) AS lastdate
FROM visitors_history
GROUP BY visitors_history) AS vh
2. Вопрос был - если только последнее
3. Вместо LEFT JOIN вам нуже INNER JOIN
Джойните вторую и третью таблицы с результатом из пункта 1
Далее - блок WHERE, там никаких вложенных селектов не требуется
4. Приводите к NULL, проверяйте только но NOT NULL
5. Название и версия SQL-сервера - неактуально, требовалось, если бы на первый вопрос был ответ "только последнее"
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967802
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
crutchmaster,
это да. Но как мне вытащить это в подзапрос?
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967813
11332266
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
crutchmaster,
потому что мне надо сравнивать только день и месяц. а таймштамп приводит всё к год,месяц,день час,минута,секунда.
мне год не нужен.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967819
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
11332266,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select 
...
from x left join y,
left join z,
(SELECT id,a,b,c from x,y,z where ...) as e
where
x.id = e.id, 
...
group by
...
order by
...
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39967840
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Очепятался. Группировка по айдишным полям
[quot paver#22148585]
11332266

1. Тогда группировка по 2 id-полям, получение максимальной даты по группировке.
(SELECT visitor_id, shop_id, MAX(date) AS lastdate
FROM visitors_history
GROUP BY visitor_id, shop_id) AS vh
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39968080
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
11332266
мне год не нужен.
Что вы будете делать 25 декабря 2020 года с теми, кто родился 4 января? У вас до конца этого года еще есть время подумать, а до тех пор вам год действительно не нужен.
...
Рейтинг: 0 / 0
Помогите пожалуйста оптимизировать запрос!
    #39968101
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну, как-то так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT `wvh`.`visitor_id`,`wvs`.`title`, `wvi`.`full_name`,`wvi`.`birth`,`wvi`.`email`,`wvi`.`telephone`,`wvi`.`city`,
       `wvh`.`last_visit`,`wvs`.`birthday_tel_bot_chat_id`
FROM (SELECT `visitor_id`, shop_id, MAX(date) AS last_visit
      FROM `wifi_visitors_history`
      WHERE date > unix_timestamp(180602)
      GROUP BY visitor_id, shop_id) AS `wvh` 
JOIN `wifi_visitors_info` as `wvi` on `wvi`.`visitor_id` = `wvh`.`visitor_id`
JOIN `wifi_visitors_shop` as `wvs` on `wvh`.`shop_id` = `wvs`.`shop_id`
WHERE `wvi`.`birth` IS NOT NULL
AND `wvs`.`birthday_tel_bot_chat_id` IS NOT NULL
AND (date_format(from_unixtime(`wvi`.`birth`),'%m-%d') = date_format(CURRENT_DATE + INTERVAL 9 DAY),'%m-%d') OR
     date_format(from_unixtime(`wvi`.`birth`),'%m-%d') = date_format(CURRENT_DATE + INTERVAL 10 DAY),'%m-%d'))
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите пожалуйста оптимизировать запрос!
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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