powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как правильно построить индекс. Получение последнего значения по дате
7 сообщений из 7, страница 1 из 1
Как правильно построить индекс. Получение последнего значения по дате
    #39967159
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть табличка с показаниями датчиков (самих датчиков около 20 тыс )

counter_id - идентификатор датчика
val - значение
val_date - дата значения

Значений в табличке сотни миллионов уже

В табличку постоянно валятся новые показания, табличка секционирована по месяцу даты и по данному полю индекс (локальный).
Ранее надо было всегда вытаскивать таблицу значений за определённый календарный день и такая схема прекрасно работала.

А сейчас вдруг появилась необходимость, если для для какого-то датчика в запрошенном дне НЕ было значения, то отражать последнее по дате значение. Вот что-то я на "последнее по дате" заткнулся немного при таком размере таблицы.

Если бы всегда нужны были данные на текущий день - можно было бы где-то хранить дату последнего показания для каждого счётчика, а тут получается, что могут запросить данные за любой день и если для какого-то счётчика дата попадает в "дырку" надо именно для этого счётчика искать когда же было последнее показание.

Т.е. было просто:
Код: plsql
1.
SELECT  *  FROM  counter_val  WHERE  val_date  >=  to_date('01.01.2020')  and val_date < to_date('02.01.2020') 


Код: plaintext
1.
2.
3.
4.
SELECT STATEMENT                    
  PARTITION RANGE SINGLE            
   TABLE ACCESS BY LOCAL INDEX ROWID
    INDEX RANGE SCAN                

А теперь мне для начала для каждого счётчика нужно получить последнюю дату (меньшую или равную указанной), в которой есть значение
Код: plsql
1.
2.
SELECT  counter_id , max(val_date)  FROM  counter_val  WHERE  val_date  <  to_date('02.01.2020') 
GROUP BY counter_id


Код: plaintext
1.
2.
3.
4.
SELECT STATEMENT           
  HASH GROUP BY            
   PARTITION RANGE ITERATOR
    TABLE ACCESS FULL      


Фуллскан полюбому? на трёхстах миллионах значений уже за две минуты переваливает :(

Никакой путной структуры для хранения таких данных "с дырками" нет, чтобы можно было на любую дату быстро вытащить последнее значение?
Пытаться насильно заполнять "дырки" последним значением ?

Обидно то, что "дырки" небольшие и я заведомо знаю, что если в каком-то дне нет показания, то за последние три-четыре дня точно оно есть.... но базе этого не объяснить.

--------------------------------------------------------------
Запомните, товарищи офицеры, чтобы ничего не делать, надо уметь делать все.
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967165
exciter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
anvano,

LAG() IGNORE NULLS?
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967167
exciter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если не напутал с синтаксисом,
Код: plsql
1.
SELECT  cv.*, nvl(cv.val,LAG(cv.val) IGNORE NULLS OVER (PARTITION BY cv.counter_id ORDER BY cv.val_date))  FROM  counter_val  cv WHERE  cv.val_date  <= :date
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967169
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano

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

Как определяете факт отсутствия значения для какого-либо датчика?
Есть справочник датчиков или где?
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967170
exciter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если же в таблице вовсе нет строки на заданную дату, а не поле val_date не заполнено, то может быть, так:

Код: plsql
1.
2.
3.
4.
5.
select counter_id, 
max(val) keep(dense_rank first order by val_date desc) from 
counter_test
where val_date<=:dt
group by counter_id
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967176
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano

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

Есть. SCD2, например, с partition key по дате завершения версии.

anvano

Пытаться насильно заполнять "дырки" последним значением ?

Подход имеет право на жизнь, но требует внимательного рассмотрения:
- Кто и когда будет формировать отсутствующие значения?
- Достаточно ли часто выполняется указанный запрос по актуальному периоду, чтобы экономия на его ресурсоемкости покрыла ресурсы, необходимые для заполнения пустот?
- Можно ли разнести подготовку данных и их использование по времени?

anvano

Обидно то, что "дырки" небольшие и я заведомо знаю, что если в каком-то дне нет показания, то за последние три-четыре дня точно оно есть.... но базе этого не объяснить.


Было бы желание, а объяснить можно.
Разными способами.
Например, если справочника приборов нет:
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT counter_id
     , max(val) keep (dense_rank last order by val_date) val
     , max(val_date) val_date
  FROM  counter_val  
 WHERE  val_date  >=  to_date('01.01.2020') -5 -- поясняем базе, что искать надо с запасом в 5 дней
   and val_date < to_date('02.01.2020') 
...
Рейтинг: 0 / 0
Как правильно построить индекс. Получение последнего значения по дате
    #39967178
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как правильно построить индекс. Получение последнего значения по дате
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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