Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Медленно работает запрос. / 25 сообщений из 59, страница 1 из 3
19.11.2013, 14:33:34
    #38469946
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Здравствуйте уважаемые форумчане.

Недавно стала работать с MySQL, плаваю еще во всем. До этого писала только SQL запросы для БД Access. Там вроде особых проблем не возникало. А тут что-то запрос уж совсем медленно работает, у меня на тестовой базе до 10 минут, а у клиента вообще редко отрабатывает полностью. На Access почти аналогичный запрос работает гораздо быстрее, но там и данных значительно меньше, только одного филиала. А на MySQL скидываются данные из 30 филиалов и вот потом надо делать выборку.

Попробую в кратце описать, что у меня есть.

Есть таблица клиентов Clients с первычным ключем по двум полям ClientID, BranchID. Основное для запроса поле: TRPID - это значение присваивается клиенту, который ходит в несколько филиалов и в них уже зарегистрирован по своему ClientID, чтобы потом смотреть его общую статистику посещений.
Есть таблица посещений клиентов Visits, так же с первичным ключем по двум полям VisitID, BranchID. Которая содержит ClientID. Поле VisitIN - дата посещения. В тестовой базе 500 000 записей
И есть таблица маркетинговых расходов, которые были при посещении клиента ClientsMarketingExp с первичным ключем по двум полям ClientsMarketingExpID, BranchID. В которую входит VisitID. Одно посещение может содержать несколько расходов. В тестовой базе 95 000 записей.
Таблица Branches содержит BranchID и BranchName - название филиала.

Мне надо выбрать все посещения с маркетинговыми расходами, если таковые были, клиентов с TRPID = 70010, за заданный период. Т.е. если посещение включает два расхода, то в результате мы должны иметь и две строки. А если расходов не было, то одну сроку, в которой информация о маркетнговых расходах пустая.

В Access я все таблицы подключала через LEFT JOIN. Написала аналогичный запрос и для MySQL. Но он работает медленно. Почитала что лучше вместо LEFT JOIN использовать другой JOIN. Но не могу понять какой.

Вот мой немного упрощенный запрос, он все равно работает очень медленно.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT V.VisitID, CME.ClientsMarketingExpID, V.BranchID as BranchID, 
      V.ClientID, V.`Group` as "Group", V.ClientType, V.ClientSize, 
      V.VisitType, V.VisitIn as `In`, V.VisitOut as `Out`, V.Balance, V.Rate, V.MaxRisk, 
      V.Automat, V.MarketingSum, V.MarketingNotes,
      V.ChangeTime, V.VersionID, V.UserID, V.Is2ndVisit, V.IsTypicalClient,
      CME.Code, CME.Sum, CME.Notes, CME.PlayMachineID, 
      CME.TimeIn, CME.PlayMachineID, C.GamblerCode, 
      C.NickName, C.Type, C.TRPID, Date(Date_Format(V.VisitIn, '%Y-%m-%d')) as DateIn, IF(B.BranchName is null, Cast(V.BranchID as char), B.BranchName) as BranchName
FROM (Visits V
  LEFT JOIN  ClientsMarketingExp CME ON V.VisitID=CME.VisitID AND V.BranchID=CME.BranchID)
  LEFT JOIN Clients C ON V.ClientID=C.ClientID AND V.BranchID=C.BranchID
  LEFT JOIN Branches B ON V.BranchID=B.BranchID
WHERE V.VersionID<>-1  AND IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1 AND V.VisitIn BETWEEN '2013-10-01' AND '2013-10-30' AND C.TRPID ='70010' AND V.BranchID<>1 
ORDER BY V.VisitIn, TimeIn;



Запрос отрабатывает 4-5 минут на MySQLWorkbench и в результате возвращает 57 записей. Пробовала делать выборку сначала из таблица клиентов, а потом уже присоединять к ней визиты и расходы. На скорость почти не влияет. Выборку из клиентов и визитов делает быстро, но стоит добавить маркетинги сразу скорость падает.

Поскажите, как мне видоизменить запрос? А может нужно добавить индексы на какие-то поля?

Извините за "много букв".
...
Рейтинг: 0 / 0
19.11.2013, 14:46:27
    #38469978
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
план запроса?
...
Рейтинг: 0 / 0
19.11.2013, 14:54:49
    #38469990
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Korni,

Вы таблицы ClientsMarketingExp и Clients соединяете по LEFT JOIN, однако в секции WHERE выкидываете записи, где поля из этих таблиц оказываются NULL. Тут либо не нужно слово LEFT, либо неверные условия в секции WHERE.
...
Рейтинг: 0 / 0
19.11.2013, 14:58:14
    #38469996
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
фрагмент
Код: sql
1.
IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1

можно заменить на
Код: sql
1.
CME.Versionid<>-1
...
Рейтинг: 0 / 0
19.11.2013, 15:10:57
    #38470009
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Korni,

Для начала убирайте во FROM скобки -- они там вообще ни на фиг не нужны.

Далее, Во-первых, убирайте отсюда

LEFT JOIN Clients C ON V.ClientID=C.ClientID AND V.BranchID=C.BranchID


LEFT JOIN, заменяйте его просто JOIN -- у вас всё равно на эту таблицу условие:

C.TRPID ='70010'


Во-вторых, это условие

AND IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1

видимо должно быть в JOIN а не в WHERE.


Итого, у вас остаётся один единственный вразумительный
SARG --
V.VisitIn BETWEEN '2013-10-01' AND '2013-10-30'
Это за месяц.

Есть у вас индекс по полю VisitIn ?

Сколько записей за один месяц ?

Если их много, то шансов у запроса выполняться быстро просто нет.

Ну и если оно действительно "у клиента вообще редко отрабатывает полностью", то хочу напомнить, что на все условия JOIN-ов должны быть индексы, если JOIN по двум полям -- составные из этих двух полей.
...
Рейтинг: 0 / 0
19.11.2013, 15:11:40
    #38470011
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
ScareCrowплан запроса?

Да и без плана всё ясно.
...
Рейтинг: 0 / 0
19.11.2013, 15:32:04
    #38470053
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
несовсем. есть сильное подозрение на отсутсвие индексов по полям джойна.
...
Рейтинг: 0 / 0
19.11.2013, 15:42:55
    #38470073
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
miksoftKorni,

Вы таблицы ClientsMarketingExp и Clients соединяете по LEFT JOIN, однако в секции WHERE выкидываете записи, где поля из этих таблиц оказываются NULL. Тут либо не нужно слово LEFT, либо неверные условия в секции WHERE.

что-то я не понимаю, где у меня такие условия в секции WHERE?
...
Рейтинг: 0 / 0
19.11.2013, 15:46:10
    #38470075
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Korni,

Я явным образом написал.
...
Рейтинг: 0 / 0
19.11.2013, 15:47:00
    #38470077
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
KornimiksoftKorni,

Вы таблицы ClientsMarketingExp и Clients соединяете по LEFT JOIN, однако в секции WHERE выкидываете записи, где поля из этих таблиц оказываются NULL. Тут либо не нужно слово LEFT, либо неверные условия в секции WHERE.что-то я не понимаю, где у меня такие условия в секции WHERE?IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1 и C.TRPID ='70010'
...
Рейтинг: 0 / 0
19.11.2013, 15:57:08
    #38470090
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
MasterZivKorni,

Для начала убирайте во FROM скобки -- они там вообще ни на фиг не нужны.

скобки убрала - это отголосок синтаксиса Access'a.

MasterZivДалее, Во-первых, убирайте отсюда

LEFT JOIN Clients C ON V.ClientID=C.ClientID AND V.BranchID=C.BranchID

LEFT JOIN, заменяйте его просто JOIN -- у вас всё равно на эту таблицу условие:

C.TRPID ='70010'

заменила

MasterZivИтого, у вас остаётся один единственный вразумительный
SARG --
V.VisitIn BETWEEN '2013-10-01' AND '2013-10-30'
Это за месяц.

Есть у вас индекс по полю VisitIn ?

Сколько записей за один месяц ?

Если их много, то шансов у запроса выполняться быстро просто нет.

Ну и если оно действительно "у клиента вообще редко отрабатывает полностью", то хочу напомнить, что на все условия JOIN-ов должны быть индексы, если JOIN по двум полям -- составные из этих двух полей

посмотрела записей за месяц в среднем 23 000.
Добавила индекc по VisitIn и по полям VisitID и BranchID в таблице ClientsMarketingExp

В результате запрос отрабатывает за 45 секунд.

MasterZivВо-вторых, это условие

AND IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1

видимо должно быть в JOIN а не в WHERE.
Здесь надо бы данные обновить на сервере и тогда можно будет убрать это условие.

Трудно с клиентом работать, он не хочет полностью мигрировать на MySQL сервер. Филиалы работают на Access и часть данных уходит на сервер. И они потом уже работают с обобщенными данными по филиалам.

Можно ли еще что-то улучшить или 45 секунд уже хороший результат? Компик у меня староват, может будь он помощнее и запрос веселее будет работать?
...
Рейтинг: 0 / 0
19.11.2013, 15:59:39
    #38470095
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
explain запроса таки дайте
...
Рейтинг: 0 / 0
19.11.2013, 16:02:00
    #38470098
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
ScareCrowexplain запроса таки дайте
а как его делать? Я только осваиваю MySQL.
...
Рейтинг: 0 / 0
19.11.2013, 16:04:37
    #38470102
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
перед запросом написать explain
выполнить.
...
Рейтинг: 0 / 0
19.11.2013, 16:11:18
    #38470115
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
ScareCrow,
вот что получилось
...
Рейтинг: 0 / 0
19.11.2013, 16:23:50
    #38470142
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
вам точно нужны 45 тыщ строк?
...
Рейтинг: 0 / 0
19.11.2013, 16:36:00
    #38470169
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
точно НЕ нужны.
если бы я еще понимала откуда они берутся, ведь месяц в среднем 23 тысячи.
...
Рейтинг: 0 / 0
19.11.2013, 16:47:09
    #38470190
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
из за джойнов скорее всего. попробуйте убирать джойны и смотреть сколько строк получается.
либо из за устаревшей статистики. попробуйте сделать analyze table для всех таблиц.
...
Рейтинг: 0 / 0
19.11.2013, 17:23:59
    #38470254
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
ScareCrow,
убрала все джойны. Оставила только выборку из таблицы визитов. Explain все равно выдает 45 тысяч записей. Хотя если запускаю сам SELECT, он мне в результате запроса дает 21 тысячу.
вот сам запрос
авторexplain
SELECT V.VisitID, V.BranchID,
V.ClientID, V.`Group` as "Group", V.ClientType, V.ClientSize,
V.VisitType, V.VisitIn as `In`, V.VisitOut as `Out`, V.Balance, V.Rate, V.MaxRisk,
V.Automat, V.MarketingSum, V.MarketingNotes,
V.ChangeTime, V.VersionID, V.UserID, V.Is2ndVisit, V.IsTypicalClient
FROM Visits V
WHERE V.VersionID<>-1 AND V.VisitIn BETWEEN '2013-10-01' AND '2013-10-30' AND V.BranchID<>1
ORDER BY V.VisitIn
LIMIT 500000

Сделала analyze table. В результате получаю "status OK". Или я не то делаю, или там действительно все хорошо.
авторanalyze table visits - это надо было делать?
...
Рейтинг: 0 / 0
19.11.2013, 17:27:41
    #38470264
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Еще убрала из основного запроса условие IF(IsNull(CME.Versionid),0,CME.VersionID)<>-1. Оказалось, в программе баг и это поле вообще на сервер не уходит. Но на скорость выполнения запроса это никак не повлияло. Так и осталось 40 секунд.
...
Рейтинг: 0 / 0
19.11.2013, 17:28:14
    #38470265
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
ну понятно. вам сколько записей то нужно? ставьте limit сколько нужно.
дальше варианта 2. или подкрутить sort_buffer_size чтобы убрать filesort или добавить в таблицу Visits поле TimeIn из ClientsMarketingExp и сделать индекс (VisitIn, TimeIn )
...
Рейтинг: 0 / 0
19.11.2013, 17:43:45
    #38470285
Korni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
Мне все записи нужны. В результате моего запроса возвращается всего 57 записей.

Убрала сортировку из запроса. Время выполнения не изменилось.

Я еще думала, а не лучше ли начать с таблицы клиентов и уже к ней джойнить остальные таблицы? Если делать выборку из таблицы клиентов по моему условию, там всего 10 записей будет и сама таблица клиентов гораздо меньше визитов. А потом к ним уже "лепить" посещения. Или это на скорость работы не влияет?
...
Рейтинг: 0 / 0
19.11.2013, 17:49:59
    #38470294
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
авторУбрала сортировку из запроса. Время выполнения не изменилось.

explain?

авторЯ еще думала, а не лучше ли начать с таблицы клиентов и уже к ней джойнить остальные таблицы
оптимизатор это сам разруливает.
...
Рейтинг: 0 / 0
19.11.2013, 18:04:34
    #38470316
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
фильтром по дате отфильтровывается 23 тыщи
автормесяц в среднем 23 тысячи.
вопрос - чем отфильтровывется еще 22943 записи?

ибо
авторВ результате моего запроса возвращается всего 57 записей.
...
Рейтинг: 0 / 0
19.11.2013, 18:57:19
    #38470367
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленно работает запрос.
KorniМне все записи нужны. В результате моего запроса возвращается всего 57 записей.

Убрала сортировку из запроса. Время выполнения не изменилось.

Я еще думала, а не лучше ли начать с таблицы клиентов и уже к ней джойнить остальные таблицы? Если делать выборку из таблицы клиентов по моему условию, там всего 10 записей будет и сама таблица клиентов гораздо меньше визитов. А потом к ним уже "лепить" посещения. Или это на скорость работы не влияет?

Не лучше. У вас фильтр по визитам.
Но фильтр не самый лучший -- 27тыщ строк.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Медленно работает запрос. / 25 сообщений из 59, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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