Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите в оптимизации запроса. / 25 сообщений из 25, страница 1 из 1
13.11.2015, 13:18
    #39102867
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Есть таблица в которую записываются данные о расположении абонента:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE GSMDATA (
    ID          	INTEGER NOT NULL,
    ABONENTID     	INTEGER,
    XCOORD     	 	FLOAT,
    YCOORD      	FLOAT,
    TIMESESSION   	TIMESTAMP,
    CORRECTCOORDS 	SMALLINT
);



Подскажите, можно ли составить запрос так, чтобы мне возвращались последние данные от каждого абонента?

Если просто сделать такой запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
        SELECT
            AbonentId, MAX(TimeSession) as TimeSession
        FROM
            GsmData
        WHERE 
        	CorrectCoords = 1
        GROUP BY
            AbonentId


то я получаю, для каждого абонента, когда последний раз эти данные были. Только ID и время. А мне нужно получить еще и координаты какие были на тот момент.

Сейчас сделал через процедуру:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    FOR
        SELECT
            AbonentId, MAX(TimeSession) as TimeSession
        FROM
            GsmData
        WHERE 
        	CorrectCoords = 1
        GROUP BY
            AbonentId
        INTO
            :AbonentId,:TimeSession
    DO BEGIN
       SELECT
            Id,XCOORD,YCOORD
       FROM
           GsmData gd
       WHERE
       		(gd.TimeSession = :TimeSession) AND
       		(gd.AbonentId = :AbonentId)
       INTO
            :Id, :AbonentId, :TimeSession, :XCOORD, :YCOORD;
       SUSPEND;
    END


Только мне кажется это изврат какой-то ну и долго считается. Можно это сделать одним запросом, как думаете?
...
Рейтинг: 0 / 0
13.11.2015, 13:33
    #39102888
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Код: sql
1.
2.
3.
4.
5.
create view gsm_data_last as
select g1.* from gsmdata g1 
join (
   select ID, MAX(TimeSession) as TimeSession, AbonentId FROM GsmData GROUP BY AbonentId
) g2 on g1.ID = g2.ID  
...
Рейтинг: 0 / 0
13.11.2015, 13:35
    #39102892
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShimну и долго считается

а индексы нужные есть?

и зачем это (gd.TimeSession = :TimeSession) AND (gd.AbonentId = :AbonentId) когд у тебя первичный ключ ID есть?
...
Рейтинг: 0 / 0
13.11.2015, 13:37
    #39102896
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
А вообще смотря по соотношению как часто ты пишешь и как часто считаешь. Можно и столбец завести, с признаком последнести данной строчки, или отдельную таблицу AbonentID -> ID (gsmdata pk)
...
Рейтинг: 0 / 0
13.11.2015, 13:40
    #39102899
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Arioch
Код: sql
1.
2.
3.
4.
5.
create view gsm_data_last as
select g1.* from gsmdata g1 
join (
   select ID, MAX(TimeSession) as TimeSession, AbonentId FROM GsmData GROUP BY AbonentId
) g2 on g1.ID = g2.ID  



Так не получается. Не выполняется даже отдельно внутренний запрос:
Код: sql
1.
   select ID, MAX(TimeSession) as TimeSession, AbonentId FROM GsmData GROUP BY AbonentId


Ошибка:
Код: sql
1.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
...
Рейтинг: 0 / 0
13.11.2015, 13:48
    #39102914
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AriochА вообще смотря по соотношению как часто ты пишешь и как часто считаешь. Можно и столбец завести, с признаком последнести данной строчки, или отдельную таблицу AbonentID -> ID (gsmdata pk)

Сейчас есть отдельная таблица ActualInfo, в которую я пишу последние данные. На AfterInsert таблицы GsmData я или добавляю, или обновляю в ней данные. Но так, как в GsmData данные сыпятся штук по 100 в секунду, растет количество версий записей в ActualInfo. И через какое-то время вся база начинает тормозить. Для сборки мусора приходится по таймеру раз в какое-то время делать
Код: sql
1.
SELECT COUNT(*) FROM ActualInfo


Так, в принципе, все работает. Только мне кажется есть более простые пути без доп таблиц и дублирования данных. Вот ищу. 6-)
...
Рейтинг: 0 / 0
13.11.2015, 15:10
    #39103002
m7m
m7m
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShim,

насколько понимаю нужны оконные функции (в тройке они есть)
...
Рейтинг: 0 / 0
13.11.2015, 16:21
    #39103087
Naf
Naf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Код: sql
1.
2.
3.
4.
select g1.* from gsmdata g1 
join (
   select MAX(TimeSession) as TimeSession, AbonentId FROM GsmData GROUP BY AbonentId
) g2 on g1.AbonentId = g2.AbonentId and g1.TimeSession = g2.TimeSession
...
Рейтинг: 0 / 0
13.11.2015, 17:03
    #39103129
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Naf,

Вот это то, что нужно. Спасибо!
...
Рейтинг: 0 / 0
13.11.2015, 17:04
    #39103130
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
m7mAndreyShim,
насколько понимаю нужны оконные функции (в тройке они есть)
Ну на 3-ку пока не хочется переходить. Но про них я почитаю... Пасиб!
...
Рейтинг: 0 / 0
13.11.2015, 17:33
    #39103154
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShim,

ктати, можно ли считать, что ID мнонотонно возрастает ? тогда

Код: sql
1.
2.
3.
4.
select g1.* from gsmdata g1 
join (
   select MAX(ID) as ID, AbonentId FROM GsmData GROUP BY AbonentId
) g2 on g1.Id = g2.Id 



просто потому что на PK уже есть индекс

Интересно, сможет ли FB2 для внутреннего запроса использовать индекс descending(AbonentID, ID)

...соотв для предыдущего запроса - descending(AbonentID, TimeSession)
...
Рейтинг: 0 / 0
13.11.2015, 18:04
    #39103178
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Ariochктати, можно ли считать, что ID мнонотонно возрастает ? тогда

Код: sql
1.
2.
3.
4.
select g1.* from gsmdata g1 
join (
   select MAX(ID) as ID, AbonentId FROM GsmData GROUP BY AbonentId
) g2 on g1.Id = g2.Id 



Да, вы правы, так и есть. Действительно, ко времени можно и не привязываться.


AriochИнтересно, сможет ли FB2 для внутреннего запроса использовать индекс descending(AbonentID, ID)
...соотв для предыдущего запроса - descending(AbonentID, TimeSession)

Про это не знаю.
...
Рейтинг: 0 / 0
13.11.2015, 19:19
    #39103222
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShim,

так проверьте
...
Рейтинг: 0 / 0
13.11.2015, 20:26
    #39103251
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShim,

тип float используется осмысленно, или по незнанию?
...
Рейтинг: 0 / 0
16.11.2015, 13:41
    #39104430
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AriochAndreyShim,
так проверьте
Что-то я не очень понял, что вы имеете в виду. :/
...
Рейтинг: 0 / 0
16.11.2015, 13:52
    #39104448
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
kdvAndreyShim,
тип float используется осмысленно, или по незнанию?
Вы имеете ввиду, что float 32 бита? Или что-то еще? Для хранения координат это от -180 до 180 - 5 знаков после запятой вроде хватает. Изменения в 5-м знаке это меньше метра. У нас координаты не такие точные приходят, чтобы их хранить в двойной точности.
...
Рейтинг: 0 / 0
16.11.2015, 14:12
    #39104484
Naf
Naf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShimИзменения в 5-м знаке это меньше метра. У нас координаты не такие точные приходят, чтобы их хранить в двойной точности.

Используйте NUMERIC(8,5)
...
Рейтинг: 0 / 0
16.11.2015, 14:58
    #39104554
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShimВы имеете ввиду, что float 32 бита?
я имею в виду, что float это вещественное число с крайне низкой точностью, которое сейчас мало для чего годится.
И в нем, кстати, некоторые числа (дробные) даже и не могут храниться, они тут же искажаются. Например, 1.88 сразу превращается в 1.87999999523163.
http://www.ibase.ru/devinfo/round.htm
...
Рейтинг: 0 / 0
16.11.2015, 15:23
    #39104577
AndreyShim
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Naf Используйте NUMERIC(8,5)

kdvя имею в виду, что float это вещественное число с крайне низкой точностью, которое сейчас мало для чего годится.
И в нем, кстати, некоторые числа (дробные) даже и не могут храниться, они тут же искажаются. Например, 1.88 сразу превращается в 1.87999999523163.
http://www.ibase.ru/devinfo/round.htm

Понял. Спасибо!
...
Рейтинг: 0 / 0
16.11.2015, 16:47
    #39104696
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
kdvя имею в виду, что float это вещественное число с крайне низкой точностью, которое сейчас мало для чего годитсяТрёхмерная графика - не так уж мало
...
Рейтинг: 0 / 0
16.11.2015, 17:30
    #39104780
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Basil A. Sidorov,

Звучит как "приборы - 120"
В какой части трёхмерной графики всё завязано на float?
...
Рейтинг: 0 / 0
16.11.2015, 18:37
    #39104878
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Объекты трёхмерной графики разбиваются на полигоны (треугольники).
Координаты полигонов задают вещественными числами. Как правило - именно float.
...
Рейтинг: 0 / 0
17.11.2015, 02:52
    #39105094
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Basil A. Sidorov,

а при чем тут полигоны? У автора таблица называется GSMDATA, т.е. речь идет про GSM, и координаты устройства (названия столбцов тоже намекают).
Для координат рекомендуют вещественное с точностью 10 цифр и 6 после точки. Т.е. numeric(10,6).
Float имеет точность в 7 цифр, так что в 10 цифр он уже не попадает. Double precision - 15 цифр.
Так что лучше использовать numeric(10,6), который будет храниться в bigint.

Понятно, конечно, что и float покатит. Но для определенных координат он будет вносить свою погрешность.
...
Рейтинг: 0 / 0
17.11.2015, 09:20
    #39105188
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
Basil A. Sidorov,

Пиши сразу, что в D3DX. А так, в общем - неправда.
...
Рейтинг: 0 / 0
17.11.2015, 11:55
    #39105382
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите в оптимизации запроса.
AndreyShim,

я имел в виду создать индекс и проверить использует ли его внутренний запрос 18413603
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите в оптимизации запроса. / 25 сообщений из 25, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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