Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обойтись без объединения таблиц / 9 сообщений из 9, страница 1 из 1
01.03.2015, 17:39:41
    #38891800
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Доброго времени суток!

Никак не могу решить следующую задачу:

Имеется таблица событий (полученная запросом), имеющая чуть более 600к записей такого вида
triggeridtimevalue46397 2015-02-20 11:23:21 046397 2015-02-20 11:11:22 146397 2015-02-12 10:35:21 047654 2015-02-20 11:23:48 047654 2015-02-20 11:10:48 147654 2015-02-15 12:15:48 0

Нужно для каждого значения time, принадлежащего определенному triggerid, найти время следующего события, т.е. минимальное время из больших данного для данного triggerid.

Нужно получить слеюующую таблицу:
triggeridtimevaluenexttime46397 2015-02-20 11:23:21 0 null46397 2015-02-20 11:11:22 12015-02-20 11:23:2146397 2015-02-12 10:35:21 0 2015-02-20 11:11:2247654 2015-02-20 11:23:48 0 null47654 2015-02-20 11:10:48 12015-02-20 11:23:4847654 2015-02-15 12:15:48 02015-02-20 11:10:48

Такие задачи обычно решаются через join, что я, собственно, и сделал.
Работает отлично, если я в запросе укажу небольшое кол-во triggerid. Но вот если не ограничивать запрос по их кол-ву, то запрос зависает, т.е. по графику утилизации процессора сервера БД видно, что БД ничего не выводит, просто забивает процессор. И это, в принципе, логично, он из-за join'а делает таблицу 600к х 600к строк.

Может можно реализовать как-то эту задачу не прибегая к join? Или просто как-то модернизировать код?

Код:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT 
e.objectid as triggerid,
FROM_UNIXTIME(e.clock) as time,
e.`value`,
MIN(FROM_UNIXTIME(e2.clock)) as nextTime
FROM
`events` e
JOIN `events` e2 ON e2.objectid=e.objectid
JOIN functions f ON f.triggerid=e.objectid AND f.triggerid=e2.objectid
JOIN `triggers` t ON t.triggerid=e.objectid AND t.triggerid=e2.objectid
JOIN items i ON i.itemid=f.itemid
JOIN `hosts` h ON h.hostid=i.hostid
JOIN hosts_groups hg ON hg.hostid=h.hostid
WHERE 
e.object=0
AND hg.groupid=13
AND t.description='Availability'
AND e.clock<e2.clock
GROUP BY triggerid, time
ORDER BY triggerid, time DESC



Вот этот join:
Код: sql
1.
JOIN `events` e2 ON e2.objectid=e.objectid
...
Рейтинг: 0 / 0
01.03.2015, 20:14:00
    #38891875
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Попробовал реализовать через функцию:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE FUNCTION NextTime2(`id` int,`curtime` int) RETURN int(11)
BEGIN
DECLARE nextTime INT;
SELECT 
MIN(e.clock)
INTO nextTime
FROM
`events` e
WHERE 
e.objectid=id
AND e.clock>curtime;
RETURN nextTime;
END



Соответственно, в предыдущем коде изменил селект:
Код: sql
1.
2.
3.
4.
5.
SELECT 
e.objectid as triggerid,
FROM_UNIXTIME(e.clock) as Time,
e.`value`,
FROM_UNIXTIME(NextTime2(e.objectid,e.clock)) as nextTime



По моим подсчетам, на одну запись уходит примерно 1-1,5 сек. Учитывая, что записей больше 600к, нужно еще быстрее...

Кто-нибудь поможет?
...
Рейтинг: 0 / 0
01.03.2015, 20:27:05
    #38891882
retvizan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Такую задачу нужно решать через пользовательские переменные. Это как раз оправданный случай их применения. Посмотрите эту статью .
...
Рейтинг: 0 / 0
01.03.2015, 20:28:12
    #38891885
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Pim.,

Может, изначально условия поменять? Обычно геморр с реализацией бывает из-за кривых входных параметров. Скажем, попробовать настроить железки на запись прямо в базу, либо таки добавить в файлы id, чтобы они и его писали.
Следующий вариант - загрузил файлы, допустим, там у тебя 1000000 записей. Но железкам-то твоим похрен, в какой файл писать, верно? Значит, если ты сам лично в этот файл добавишь колонку id - то сможешь плясать от нее.

Смотри, вот у тебя было:

CoolRecords.txt
Up at 12-12-2014
Down at 14-12-2014

Я тебе предлагаю самому переписать этот файл. Станет так:

LOADED Up at 12-12-2014
LOADED Down at 14-12-2014

Теперь твои железки снова туда пишут. Получаешь ты файл такой:
CoolRecords.txt

LOADED Up at 12-12-2014
LOADED Down at 14-12-2014
Up 01-03-2015

И далее грузишь только те записи, у которых нет признака LOADED. Еще лучше, конечно, туда не LOADED, а дату-время загрузки писать.
...
Рейтинг: 0 / 0
01.03.2015, 20:31:29
    #38891886
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Сорри, не туда вообще.
...
Рейтинг: 0 / 0
01.03.2015, 20:33:51
    #38891887
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
retvizan,

Спасибо. Почитаю.
...
Рейтинг: 0 / 0
01.03.2015, 22:56:30
    #38891924
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
retvizanТакую задачу нужно решать через пользовательские переменные. Это как раз оправданный случай их применения. Посмотрите эту статью .

Спасибо! Это то, что надо. Только вот я не очень с этой темой разобрался.
Не мог бы кто-нибудь помочь придумать запрос с использованием пользовательский переменных в рамках данной задачи?
...
Рейтинг: 0 / 0
02.03.2015, 01:10:36
    #38891972
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
retvizanТакую задачу нужно решать через пользовательские переменные. Это как раз оправданный случай их применения. Посмотрите эту статью .

Спасибо Вам огромное! Я думал, у меня никогда не получится это сделать. 3 дня бился головой об стол...

Итоговый код:

Код: 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.
SET @next_date=NULL, @id=0;
SELECT
t.triggerid,
t.time,
t.`value`,
if(@id=t.triggerid, CAST(@next_date AS CHAR(100) CHARACTER SET utf8), (null) AND (@id:=t.triggerid)) `nextdate`,
@next_date:=t.time
FROM
(
SELECT 
e.objectid as triggerid,
FROM_UNIXTIME(e.clock) as time,
e.`value`
FROM
`events` e
JOIN functions f ON f.triggerid=e.objectid
JOIN `triggers` t ON t.triggerid=e.objectid
JOIN items i ON i.itemid=f.itemid
JOIN `hosts` h ON h.hostid=i.hostid
JOIN hosts_groups hg ON hg.hostid=h.hostid
WHERE 
e.object=0
AND hg.groupid=13
AND t.description='Availability'
ORDER BY e.objectid, e.clock DESC
) as t
...
Рейтинг: 0 / 0
02.03.2015, 01:15:25
    #38891973
Pim.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обойтись без объединения таблиц
Время выполнения запроса 13 секунд!
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обойтись без объединения таблиц / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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