powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Получение последних значений по тегам из БД SQL. Посоветуйте подход
20 сообщений из 20, страница 1 из 1
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968829
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, друзья!
Имею задачу, когда значения параметров хранятся в реляционной БД SQL Oracle.
Вот фрагмент, который иллюстрирует эту примитивную структуру хранения данных и тот совершенно типовой запрос, которым мы достаем из этой БД нужные нам данные. А нужно нам всегда одно и то же - последнее значение (val) по дате (dt) для каждого тега (id).
Прошу обратить внимание, что по некоторым тегам (id) последние значения зарыты глубоко в истории (см. 444).

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with       
  table_1 as        
    (       
        select 111 as id, to_date('11/05/2020', 'dd/mm/yyyy') as dt, 13 as val from dual union all       
        select 222 as id, to_date('05/05/2020', 'dd/mm/yyyy') as dt, 10 as val from dual union all  
        select 333 as id, to_date('29/04/2020', 'dd/mm/yyyy') as dt, 19 as val from dual union all  
        select 222 as id, to_date('29/04/2020', 'dd/mm/yyyy') as dt, 18 as val from dual union all  
        select 333 as id, to_date('23/04/2020', 'dd/mm/yyyy') as dt, 17 as val from dual union all  
        select 111 as id, to_date('15/04/2020', 'dd/mm/yyyy') as dt, 18 as val from dual union all  
        select 222 as id, to_date('13/04/2020', 'dd/mm/yyyy') as dt, 11 as val from dual union all  
        select 111 as id, to_date('30/03/2020', 'dd/mm/yyyy') as dt, 14 as val from dual union all  
        select 444 as id, to_date('06/05/1987', 'dd/mm/yyyy') as dt, 12 as val from dual   
    )       

select id, dt, val from table_1   
where (id, dt) in (select id, max(dt) from table_1 where id in (select * from oldDtTab) group by id) 



Естественно, тегов много, значений тоже. Такой простой запрос дает очень плохие результаты по производительности (запрос длится до 10 минут).
Прошу вас посоветовать, как можно оптимизировать подход к запросу данных в такой ситуации? Какие приемы можно тут применить?
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968830
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Оконные функции.
2. Хранимые агрегаты.
3. Они же в виде материализованного представления.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968831
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
Спасибо за оперативный ответ!

Можно Вас попросить сказать еще пару фраз на счет оконных функций?
Верно ли я понимаю, что целесообразно проделать тот же "поиск максимальной даты" и "запрос по максимальной дате" В ОКНЕ ПО ТЕГУ (ID)?
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968832
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, это "последнее/первое значение" в порядке даты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968837
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
Вы примерно это имели в виду?
Код: plsql
1.
2.
3.
select id, dt, val from table_1 
where (id, dt) in (select distinct id, max(dt) over(partition by id) mDt from table_1)
order by id
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968840
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Begimot441Вы примерно это имели в виду?

Нет, подзапрос тут совсем не нужен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968853
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
Вас понял! Поискал и составил такой запрос. Так верно или какую то я ерунду составил?

Код: plsql
1.
2.
3.
4.
5.
select distinct first_value (id) over(partition by id order by dt DESC) id, 
                first_value (dt) over(partition by id order by dt DESC) mDt,
                first_value (val) over(partition by id order by dt DESC) val
from table_1 
order by id
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968857
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
точнее, так:

Код: plsql
1.
2.
3.
4.
5.
select distinct id, 
                first_value (dt) over(partition by id order by dt DESC) mDt,
                first_value (val) over(partition by id order by dt DESC) val
from table_1 
order by id
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968859
PuM256
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Begimot441,

Можно без аналитики - Group By + keep dense_rank
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968863
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PuM256
Begimot441,

Можно без аналитики - Group By + keep dense_rank


Нельзя, посколько строк с dt = max(dt) для id может быть > 1.

SY.
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968868
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

А у меня получилось. По-моему, все прекрасно!
Код: plsql
1.
2.
select id, max(dt) dt, max(val) keep (dense_rank first order by id, dt desc) val 
from table_1 group by id;



Я не написал, а это, видимо, важно: ID + DT уникальны.

Завтра проверю, как будет работать на реальной БД
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968898
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Begimot441,

row_number() не проще?

.....
stax
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968928
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,
Вы имеете в виду так?

Код: plsql
1.
2.
3.
4.
5.
Select id, dt, val from (
                        select id, dt, val, row_number()  over(partition by id order by dt desc) rNum from table_1
                         ) t
where t.rNum = 1
order by id
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968952
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, помогайте!

Не тянет последный запрос. Время выполнения около 3 минут.
Что в таких случаях еще делают?
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968973
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Друзья, на практике получаются противоречивые результаты.
Вот старый запрос. Он работает секунду
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
,ppdFact AS
(
	SELECT well_id wid,value val FROM WELLOP_INT.V_WELL_MEASURE_OR WHERE measure_type_id=7086 AND measure_date>sysdate-90 
		AND (well_id,measure_date) IN
						(
						SELECT well_id, max (measure_date) FROM WELLOP_INT.V_WELL_MEASURE_OR 
						WHERE measure_type_id=7086 AND well_id IN (SELECT DISTINCT ppdId FROM kTab) AND measure_date>sysdate-90 
						GROUP BY well_id
						)
)
SELECT * FROM ppdFact



А вот новый запрос, что я составил исходя из полученной информации текущего топика. Он работает 20 секунд
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
,ppdFact AS
(
	SELECT well_id wid, max(value) keep (dense_rank first ORDER BY well_id, measure_date desc) val
	FROM WELLOP_INT.V_WELL_MEASURE_OR 
	WHERE measure_type_id=7086 AND measure_date>sysdate-90 AND well_id IN (SELECT DISTINCT ppdId FROM kTab)
	GROUP BY well_id
)
SELECT * FROM ppdFact



(SELECT DISTINCT ppdId FROM kTab) - дополнительный подзапрос, который сужает количество объектов для анализа (well_id)
measure_type_id=7086 - дополнительное условие

Поясните мне, пож-та, как такое может быть? Ведь второй запрос должен работать намного быстрее первого?
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968978
dmdmdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
второй запрос должен работать намного быстрее первого?

Это умозрительные соображения.

Чтобы дать конкретные рекомендации, нужен план запроса. Приведите планы.
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39968980
Begimot441
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dmdmdm,
Вот этого я и боялся.
Дело в том, что я работаю на производственной машине (т.е., не своей личной). Там стоит sqlDbx, на нем я составляю запросы.
Пытаюсь активировать "Query Plan", появляется ошибка ORA-01031: привилегий недостаточно
А это, насколько я понял из инета, отдельная тема...
Попробую аккуратно поправить, если получится...
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39969207
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Begimot441
Stax,
Вы имеете в виду так?

Код: plsql
1.
2.
3.
4.
5.
Select id, dt, val from (
                        select id, dt, val, row_number()  over(partition by id order by dt desc) rNum from table_1
                         ) t
where t.rNum = 1
order by id


да

зы
почему нет measure_type_id=7086?

pss

max(val) keep неудобен если надо много полей
.....
stax
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39969292
йцуке
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Begimot441,
Если всегда нужны последние данные, и запрашиваются они очень часто, не хотите завести отдельную таблицу, в которую будете складывать последние по времени значения?
Т.е. есть основная историческая таблица и есть таблица - срез последних значений, хранящая только последнее по времени значение тэга. При добавлении в основную таблицу нового значения тега, в таблице срезе его обновлять (точнее обновлять если есть такой тэг или добавлять если его нет).
Эта таблица-срез будет небольшая, и скорей всего всегда будет находиться в оперативной памяти.
...
Рейтинг: 0 / 0
Получение последних значений по тегам из БД SQL. Посоветуйте подход
    #39969369
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
йцуке
Если
Такого бы аналитика да тому архитектору…
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Получение последних значений по тегам из БД SQL. Посоветуйте подход
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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