powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Работа с секционированными таблицами
7 сообщений из 7, страница 1 из 1
Работа с секционированными таблицами
    #39557160
evgeny643
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток. Попалась задача на секционированные таблицы. Перекопал кучу инфы, но не представляю что еще почитать чтобы решить следующую задачку:

Таблица счетов: Account(ID, AccountNumber, ClientID, DateBegin, DateEnd), Логический ключ = ID, Интервальное секционирование по полю DateEnd, ~50 млн записей
Таблица остатков по счетам: AccountRest(ID, AccountID, DateRest, OutRestVal), Логический ключ = AccountID, списочное секционирование по DateRest, 1 500 млн записей
Таблица клиентов: Client(ID, ClientName, DateBegin, DateEnd) , Логический ключ = ID, Интервальное секционирование по полю DateEnd, ~10 млн записей

Задача: напишите запрос на SQL (с учетом диалекта и доп возможностей Oracle) возвращающий наиболее эффективно с точки зрения производительности следующие данные:
Для заданной даты получить Номера счета, наименования клиентов по этим счетам и остатки по этим счетам
Аргументируйте свой ответ

Если не учитывать секционирование, как я представляю запрос чтобы получить то что требуется в задаче будет следующим:
SELECT ac.AccountNumber, cl.Clientname, ar.OutRestVal
FROM Account ac
JOIN Client cl ON ac.ClientID = cl.ID
AND TO_DATE('2004-05-03', 'yyyy-mm-dd') BETWEEN ac.DateBegin AND ac.DateEnd
JOIN AccountRest ar ON ac.ID = ar.AccountID

Подскажите пожалуйста где почитать и как примерно подходить к решению данной задачки? Инфу по работе с секционированием в Oracle я перечитал, но как ее применить относительно данного случая??
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39557182
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with dt as (select TO_DATE('2004-05-03', 'yyyy-mm-dd') as d from dual)
SELECT ac.AccountNumber, cl.Clientname, ar.OutRestVal, dt
FROM Account ac, Client cl, AccountRest ar
where ac.ClientID = cl.ID
AND dt.d  >= ac.DateBegin AND dt.d <= ac.DateEnd
and ac.ID = ar.AccountID
and dt.d  >= cl.DateBegin AND dt.d <= cl.DateEnd
and dt.d = ar.DateRest
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39557368
evgeny643
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fogel, спасибо. Это как альтернатива моему запросу, и конечно же аккуратнее. Я с секционированием не понимаю логики работы с тремя таблицами с разными количествами записей. Конечно же секционирование позволяет ускорить запросы при обращении к каждой, но как это соотнести с разным количеством записей 50 млн, 1500 млн и 10 млн. Подозреваю, что есть какие-то общие подходы при обработке данных в такого типа таблицах.
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39557390
evgeny643,

думается, суть вопроса была в том, чтобы "посадить" условия запроса на схему секционирования таблиц и заставить работать механизм partition pruning для исключения из рассмотрения секций, не содержащих требуемых в результате выборки данных...
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39557507
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как строить:
Про индексы и распределение по секциям ничего не сказано => ждем FTS и HJ, не запариваемся.
Предполагаем, что на дату количество остатков соответствует количеству активных счетов.

- Начинаем с клиентов (с одной стороны, самая скромная табличка, с другой - ну логично же :):) )
Секционирование интервальное, по дате окончания валидности записи.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select cl.Clientname
from Client cl
where 1=1 -- тупо удобно при работе с текстом предикат
-- Обеспечиваем partition range iterator, отсеивая заведомо ненужные "старые" секции.
-- К большому сожалению, "будущие" от p_date секции придется сканировать, 
-- т.е. производительность отбора будет зависеть от того, насколько глубоко в прошлом значение p_date.
  and cl.DateEnd >= :p_date 
  and cl.DateBegin<= :p_date -- Фильтруем записи "из будущего"



- дальше без вариантов цепляем account. Без вариантов inner join, клиенты без счетов и счета без клиентов по условию не требуеются.
Секционирование учитываем аналогично предыдущему пункту

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select ac.AccountNumber, cl.Clientname
from Client cl
   , Account ac
where 1=1 -- тупо удобно при работе с текстом предикат
  and cl.DateEnd >= :p_date -- Обеспечиваем partition range iterator, key-key
  and cl.DateBegin<= :p_date -- Фильтруем записи "из будущего"
  and ac.DateEnd >= :p_date -- Обеспечиваем partition range iterator, отсеивая заведомо ненужные "старые" секции.
  and ac.DateBegin<= :p_date -- Фильтруем записи "из будущего"
  and ac.ClientID = cl.ID -- вяжем
 -- корректно отрабатываем связку версионированных данных (актуально если попросят передалать с "на дату" в "за период")
 -- WARN: тут можно слететь с HJ в NL - контролируем план
--  and ac.DateBegin < cl.DateEnd and cl.DateBegin < ac.DateEnd



- финал: забираем остатки.
В принципе, по логике тут может ждать засада - остаток на дату не обязательно сформирован по всем счетам,
и по-хорошему следовало бы поискать "ближайший".
Но это не относится непосредственно к теме учета секционирования, потому забьем для ясности изложения.
Зато к вопросу относится указание, что секционирование - списочное, т.е. надо четко "попасть" в ключ.
Поскольку в условии не указано иное, предположим, что дата в ключе обрезана до начала суток ('DD').

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT ac.AccountNumber, cl.Clientname, ar.OutRestVal
from Client cl
   , Account ac
   , AccountRest ar
where 1=1 -- тупо удобно при работе с текстом предикат
  and cl.DateEnd >= :p_date -- Обеспечиваем partition range iterator, key-key
  and cl.DateBegin<= :p_date -- Фильтруем записи "из будущего"
  and ac.DateEnd >= :p_date -- Обеспечиваем partition range iterator, отсеивая заведомо ненужные "старые" секции.
  and ac.DateBegin<= :p_date -- Фильтруем записи "из будущего"
  and ac.ClientID = cl.ID -- вяжем
  and ar.DateRest = trunc(:p_date,'DD') -- попадаем в ключ list-секционированной таблички, ждем в плане partition SINGLE
  and ac.ID = ar.AccountID -- вяжем
;
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39565406
evgeny643
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous, спасибо огромное. Долго пытался разобраться, похоже нужно больше времени )
...
Рейтинг: 0 / 0
Работа с секционированными таблицами
    #39565667
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous- финал: забираем остатки.
В принципе, по логике тут может ждать засада - остаток на дату не обязательно сформирован по всем счетам,
и по-хорошему следовало бы поискать "ближайший".

с етим и будет загвоздка, так как нет даты окончания действия остатка

раз есть секционирование по DateRest, то мож и остаток формируют за каждый день

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


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