Опишу для начала что есть и что неободимо получить.
Есть таблица с записями(~400,000 строк, 17 колонок)
Интресиют 3 столбца
1. OrderID (не уникальный, обозначает название товара, т.е. один и тот же товар мог поступать несколько раз)
2. Save_Date (дата поступления в формате 'XXXX-XX-XX')
3. Save_Time (время поступления, число обозначающее кол-во чегото(!) предположительно чтото вроде секунд или долей секунд)
Необходимо найти самое последнее(первое) время поступления каждого OrderID (т.е. опрделенную запись для каждого OrderID).
Что я делал.
SELECT orderID, MAX(TO_DAYS(Save_Date)*24+Save_Time/10000) as time
FROM market_log
GROUP BY orderID
Здесь мы находим все правильно для каждого orderID
SELECT ML.orderID, ML.Save_Date, ML.Save_Time
FROM (первый запрос) as t1, market_log as ML
WHERE TO_DAYS(ML.Save_Date)*24+ML.Save_Time/10000=t1.time AND ML.orderID=t1.orderID
LIMIT 0,1000
Тут пытаюсь найти реальные Save_Date и Save_Time для каждого OrderID
В итоге запос просто "виснет" — немог дождаться окончания.
Пытался группировать по порядку столбцы, но также натыкался на очень длинное выполнение запроса.
1. Помогите оптимизировать или както подругому составить запрос.
2. Save_Time/10000 — как сделать разрядность выше у получаемого типа float .xx ?
Здравствуйте, Trup, Вы писали:
T>1. Помогите оптимизировать или както подругому составить запрос.
Сначало поясни
1. какие индексы на эти поля есть
2. Есть ли primary key и кто он
3. Результаты запроса
select count(a.orderID), avg(a.SaveDateCount), avg(a.SaveTimeCount) from
(select orderID, count(Save_Date), count(Save_Time) from market_log) a
Тады можно будет однозначно ответить на этот вопрос.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Trup, Вы писали:
T>>1. Помогите оптимизировать или както подругому составить запрос. GZ>Сначало поясни GZ>1. какие индексы на эти поля есть GZ>2. Есть ли primary key и кто он GZ>3. Результаты запроса GZ>
GZ>select count(a.orderID), avg(a.SaveDateCount), avg(a.SaveTimeCount) from
GZ>(select orderID, count(Save_Date), count(Save_Time) from market_log) a
GZ>
GZ>Тады можно будет однозначно ответить на этот вопрос.
1. индексов на эти поля нет
2. есть поле ID — primary key
3. Дело в том что база у меня дома.
Ваш запрос на MySql вообще не пойдет, необходимо указывать по чем группировать (group by)
Могу примерно сказать что
count(a.orderID) 130,000
avg(a.SaveTimeCount) и avg(a.SaveDateCount) 3-5
Здравствуйте, Trup, Вы писали:
T>База данных MySql
T>Опишу для начала что есть и что неободимо получить.
[skip]
T>Что я делал.
T>SELECT orderID, MAX(TO_DAYS(Save_Date)*24+Save_Time/10000) as time T>FROM market_log T>GROUP BY orderID T>Здесь мы находим все правильно для каждого orderID
T>SELECT ML.orderID, ML.Save_Date, ML.Save_Time T>FROM (первый запрос) as t1, market_log as ML T>WHERE TO_DAYS(ML.Save_Date)*24+ML.Save_Time/10000=t1.time AND ML.orderID=t1.orderID T>LIMIT 0,1000 T>Тут пытаюсь найти реальные Save_Date и Save_Time для каждого OrderID T>В итоге запос просто "виснет" — немог дождаться окончания.
T>Пытался группировать по порядку столбцы, но также натыкался на очень длинное выполнение запроса.
Избавьтесь от вложенного запроса. Лучше перепешите через 2 запроса с использованием temporary table. Вложенные запросы в MySQL к сожалению не очень хорошо оптимизируются.
Здравствуйте, Trup, Вы писали:
T>1. индексов на эти поля нет T>2. есть поле ID — primary key T>3. Дело в том что база у меня дома. T>Ваш запрос на MySql вообще не пойдет, необходимо указывать по чем группировать (group by)
Звиняюсь. Невнимательность. T>Могу примерно сказать что T>count(a.orderID) 130,000 T>avg(a.SaveTimeCount) и avg(a.SaveDateCount) 3-5
Да уж. Не очень.
В MySQL я не такой уж профи, поэтому могу ошибаться. Попробуйте сделать так —
1. Создать составной индекс orderID и Save_Date.(насколько я помню, со сложными join по нескольким полям там трабла без составного индекса).
2. Попробовать выполнить следующий запрос(в мелочах могут быть ошибки, пишу сходу):
select a.orderID, a.SaveDateMax, MAX(a.Save_Time)
from
(select orderID, MAX(Save_Date) SaveDateMax from market_log group by orderID) a,
market_log b
where a.orderID=b.orderID and a.SaveDateMax=b.SaveDate
group by a.orderID, a.SaveDateMax
либо попробывать ваш вариант вместе с индексом по orderID. Возможно он даст достаточный результат. Только IMHO в данном случае переводить дату в кол-во секунд.
Здравствуйте, Trup, Вы писали: T>Походу нет. T>Поможет если установлю индекс на OrderID?
Установи индекс по всем 3-м полям. Без индекса будет производиться линейный поиск всех значений, а затем уже вычисление значения выражений с ними после where. А так всё очень сильно ускоряеться
F>Избавьтесь от вложенного запроса. Лучше перепешите через 2 запроса с использованием temporary table. Вложенные запросы в MySQL к сожалению не очень хорошо оптимизируются.
Я вот незнаю как использовать temporary table в MySql может примерчик покажите?
Всем спасибо все работает нормально (хоть и не так быстро как хотелось бы, но это уже скорей всего относится к сложности моих запросов или неправильности их составления с точки зрения оптимизирования).