#mysql
#mysql
Вопрос:
у меня такой большой запрос, и я не могу полностью перестроить приложение из-за клиента:
SELECT count(AdvertLog.id) as count,AdvertLog.advert,AdvertLog.ut_fut_tstamp_dmy as day,
AdvertLog.operation,
Advert.allow_clicks,
Advert.slogan as name,
AdvertLog.log,
(User.tx_reality_credit
-20
-(SELECT COUNT(advert_log.id) FROM advert_log WHERE ut_fut_tstamp_dmy <= day AND operation = 0 AND advert IN (168))
(SELECT IF(ISNULL(SUM(log)),0,SUM(log)) FROM advert_log WHERE ut_fut_tstamp_dmy <= day AND operation IN (1, 2) AND advert = 40341 )) AS points
FROM `advert_log` AS AdvertLog
LEFT JOIN `tx_reality_advert` Advert ON Advert.uid = AdvertLog.advert
LEFT JOIN `fe_users` AS User ON (User.uid = Advert.user or User.uid = AdvertLog.advert)
WHERE User.uid = 40341 and AdvertLog.id>0
GROUP BY AdvertLog.ut_fut_tstamp_dmy, AdvertLog.advert
ORDER BY AdvertLog.ut_fut_tstamp_dmy_12 DESC,AdvertLog.operation,count DESC,name
LIMIT 0, 15
Это занимает примерно 1,5 с, что слишком долго.
Индексы:
User.uid
AdvertLog.advert
AdvertLog.operation
AdvertLog.advert
AdvertLog.ut_fut_tstamp_dmy
AdvertLog.id
Advert.user
AdvertLog.log
Вывод Explain:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY User const PRIMARY PRIMARY 4 const 1 Using temporary; Using filesort
1 PRIMARY AdvertLog range PRIMARY,advert PRIMARY 4 NULL 21427 Using where
1 PRIMARY Advert eq_ref PRIMARY PRIMARY 4 etrend.AdvertLog.advert 1 Using where
3 DEPENDENT SUBQUERY advert_log ref ut_fut_tstamp_dmy,operation,advert advert 5 const 1 Using where
2 DEPENDENT SUBQUERY advert_log index_merge ut_fut_tstamp_dmy,operation,advert advert,operation 5,2 NULL 222 Using intersect(advert,operation); Using where
Кто-нибудь может мне помочь, потому что я пробовал разные вещи, но никаких улучшений
Комментарии:
1. Нет ли индекса
Advert.uid
? (Кстати, реквизиты для предоставления ключевой / ПОЯСНЯЮЩЕЙ информации с места в карьер.)
Ответ №1:
Запрос довольно большой, и я ожидаю, что это займет немало времени, но вы можете попробовать добавить индекс в Advert.uid, если его нет. Кроме этого, кто-то с гораздо лучшим SQL-foo, чем я, должен будет ответить на этот вопрос.
Комментарии:
1. Да, в Advert.uid есть индекс
Ответ №2:
Во-первых, ваше предложение WHERE основано на конкретном «пользователе.ИДЕНТИФИКАТОР», но в Advert_Log есть индекс по объявлению (идентификатор пользователя). Итак, сначала измените предложение WHERE, чтобы отразить это…
Where
AdverLog.Advert = 40341
Затем удалите «ЛЕВОЕ СОЕДИНЕНИЕ», чтобы просто «ПРИСОЕДИНИТЬСЯ» к пользовательской таблице.
Наконец (без полной перезаписи запроса), я бы выбрал ключевое слово «STRAIGHT_JOIN»…
select STRAIGHT_JOIN
... rest of query ...
Который сообщает оптимизатору выполнить запрос в явно указанном порядке / отношениях.
Другой областью оптимизации было бы предварительное запрашивание «точек» (подсчетов и журналов на основе рекламы и операции) один раз и получение ответа из этого (в виде подзапроса) вместо того, чтобы выполнять два запроса)… но мне было бы интересно узнать влияние выше, ГДЕ помогает JOIN и STRAIGHT_JOIN.
Кроме того, просматривается соединение с пользовательской таблицей на основе ЛИБО Advert_Log.Advert (userId), либо TX_Reality_Credit .Пользователь (другой идентификатор пользователя, который, похоже, не совпадает, поскольку соединение между Advert_Log и TX_Reality_Credit (TRC) основано на TRC.UID), если это не неверное предположение. Это может привести к ошибочным результатам, поскольку вы тестируете НЕСКОЛЬКО идентификаторов пользователей … пользователя advert и того, кто еще является «пользователем» из таблицы «TRC»… что приведет к тому, какой кредит пользователя будет применен к вычислению «баллов».
Чтобы лучше понять взаимосвязь и контекст, не могли бы вы дать дополнительные разъяснения относительно того, что находится в этих таблицах с точки зрения Advert_Log до TX_Reality_Credit, и Advert vs UID vs User…
Комментарии:
1. Привет, спасибо за интересные предложения, я попробую их завтра утром на работе, чтобы объяснить, что пользователи путаются, кто-то, кто создал это приложение, разработал его довольно плохо, я не знаю, в чем причины, но объяснить:
2. в таблице объявлений есть рекламные объявления с пользовательским полем (владельцем рекламы) в качестве внешнего ключа, и в AdvertLog записываются клики по рекламе, а также когда пользователь покупает новый кредит. Щелчок — это цифры 1,2 в поле операции, а кредит на покупку равен 0. Вот в чем проблема, потому что, когда кто-то нажимает на рекламу, он записывает в AdvertLog.advert идентификатор рекламы, но если пользователь покупает кредит, он записывает в AdvertLog.advert идентификатор пользователя (владелец рекламы), вот почему присоединение пользователя к двум таблицам
3. @user1014954, что возвращает меня к содержанию моего вопроса… Какой пользователь должен использоваться для основы tx_reality_credit. Было бы хорошо, если бы вы предоставили некоторые примеры данных, показывающие некоторый контент из каждой таблицы (ИМЕНА ПРИМЕРОВ, где это применимо), чтобы мы могли лучше понять ваши отношения и ТО, с ЧЕМ будут работать элементы…
4. я добавлю некоторую информацию об этом завтра, сейчас у меня нет доступа к данным, и я написал это там неправильно. операция 0 — щелчок, а 1,2 — покупка кредита