powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите в оптимизации запроса.
25 сообщений из 25, страница 1 из 1
Помогите в оптимизации запроса.
    #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
Помогите в оптимизации запроса.
    #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
Помогите в оптимизации запроса.
    #39102892
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyShimну и долго считается

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

и зачем это (gd.TimeSession = :TimeSession) AND (gd.AbonentId = :AbonentId) когд у тебя первичный ключ ID есть?
...
Рейтинг: 0 / 0
Помогите в оптимизации запроса.
    #39102896
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще смотря по соотношению как часто ты пишешь и как часто считаешь. Можно и столбец завести, с признаком последнести данной строчки, или отдельную таблицу AbonentID -> ID (gsmdata pk)
...
Рейтинг: 0 / 0
Помогите в оптимизации запроса.
    #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
Помогите в оптимизации запроса.
    #39102914
AndreyShim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AriochА вообще смотря по соотношению как часто ты пишешь и как часто считаешь. Можно и столбец завести, с признаком последнести данной строчки, или отдельную таблицу AbonentID -> ID (gsmdata pk)

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


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

насколько понимаю нужны оконные функции (в тройке они есть)
...
Рейтинг: 0 / 0
Помогите в оптимизации запроса.
    #39103087
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
Помогите в оптимизации запроса.
    #39103129
AndreyShim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Naf,

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

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

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

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

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

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

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

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

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

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

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


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