Несколько вопросов чайника по ораклу

marat7256

1. Какой вариант datafile лучше, обычный (типа small) или big? Если исходить из предпосылки, что данных около 500 гигабайт (включая индексы размер блока 8К, то есть обычный размер (small)датафайла будет 32Гб. Какой вариант лучше для данных, которые уже не пополняются, и для тех, которые продолжают регулярно пополняться. Грубо говоря, что лучше, 1 файл под террабайт или пара десятков файлов по 32Гб?
2. Есть таблица в почти миллиардом записей (данные со спутника, временные ряды). Загружаться могут как скопом один раз и навсегда, так и пополняться постепенно по мере прихода телеметрии.В пределах одного часа строк может быть до полутора миллионов. Задача строить графики в пределах от нескольких секунд, до, скажем, дней. Для построения графиков на больших масштабах данные усредняются. Необходимо сделать выборку как можно быстрее. Варианты:
- просто таблица с индексом по дате
- таблица разбитая на сегменты (партиции) с глобальным индексом
- таблица разбитая на сегменты с локальным индексом (то есть тоже разбитым на такие же сегменты)
- ?
Проблемы первого варианта в долгом поиске по большому индексу. Это, конечно быстрее, чем полный скан таблицы, но при миллиарде строк...
Проблема второго варианта аналогична первой, за исключением того, что на некоторых запросах поиск ведется не по индексу, а по партициям. Но внутри партиции тогда уже не работает индекс, а только полный скан.
Проблема третьего варианта в том, что размер локального индекса превышает размер самих данных. Хотя по скорости, очевидно, он самый оптимальный. Тут проблема в том, что под индекс выделяется большие куски и они могут оставаться практически пустыми, особенно в случаях, когда были проблемы с приемом данных со спутника. Разбивать на партиции разного размера - трудоемкая задача при заданном количестве данных. Возможно, имеет смысл выбрать размер партиции (в действительности интервал времени) таким образом, чтобы место под индекс использовалось бы оптимальным образом (то есть было как можно меньше пустых блоков). Пока же размер партиции выбран в один час. И в этот час может быть как 0 строк, так и полтора миллиона. Число таких партиций больше 3 тысяч. Наверное, надо увеличить размер партиций....

SergeRRRRRR

2. Имхо партиционированная таблицы с субпартициями. субпартиция по ренджу времени, партиция по флагу активности, который джобом переключается. Ну в общем вроде вы и так все правильно делаете :)

marat7256

партиция по флагу активности, который джобом переключается
Поясни. Я что-то не могу придумать ничего, кроме партицирования по времени.
И что на счет локальный/глобальный индекс?

0000

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

SergeRRRRRR

я не настоящий сварщик, вот тут подробнее.
Ну и по unixtime верно подмечено.

marat7256

Там микросекунды. Используем timestamp.

marat7256

Проблема с размером индекса вот в чем.
Локальный индекс, ка вы знаете, это по-существу отдельные индексы по каждой партиции в таблице. Их у меня более 3 тысяч. На каждый индекс выделяется память, кратная числу блоков (это какой-то параметр базы, я с ходу не помню). Так вот эта выделенная память практически пустует, ибо в реальности требуется гораздо меньше на тот объем данных, что есть в каждой партиции. Общий размер локального индекса получается просто чудовищный и превышает размер самих данных в разы. Я вижу только два варианта, найти как указать, сколько блоков выделять под индекс (или прямо при создании индекса, либо в каком-то параметре базы либо делать размер партиции (интервал времени) значительно больше. Второй вариант реализовать просто, но надо выбрать этот "хороший" размер, для чего потребуется время на создание/удаление партиций и индексов. Первый - кажется более верным, но пока не ясно куда копать :)

YUAL

Кстати а почему оракл и вообще реляционная база данных? Есть же специальные time series database как раз для хранения всяких метрик с приборов и т.п. Там по идее все эти проблемы должны быть решены.

mbolik1

1. Какой вариант datafile лучше, обычный (типа small) или big?
Лучше small. При части манипуляций будет жизнь полегче. Big придумывали для случая когда 1024 файла не хватает.
2. Есть таблица в почти миллиардом записей (данные со спутника, временные ряды). Загружаться могут как скопом один раз и навсегда, так и пополняться постепенно по мере прихода телеметрии.В пределах одного часа строк может быть до полутора миллионов. Задача строить графики в пределах от нескольких секунд, до, скажем, дней. Для построения графиков на больших масштабах данные усредняются. Необходимо сделать выборку как можно быстрее.

Честно говоря не понял проблему с локальным индексом. У тебя секции какого размера что размер индекса превышает размер секции?
Могу предложить следующие варианты решений:
0. Посмотреть на key compression — возможно это уменьшит размеры индекса. вообще будет хорошо если ты приведёшь ddl таблицы и индекса и какую-нибудь статистику.
1. Partitioned index-orginized table Тынц. — индекс будет частью таблицы
2. Materialized View Тынц. — хранить предаггрегированные данные для запросов по большим периодам.
3. Возможно стоит сжимать старые секции — уменьшиться и сама секция и индексы. Тынц.

mbolik1

Проблема с размером индекса вот в чем.Локальный индекс, ка вы знаете, это по-существу отдельные индексы по каждой партиции в таблице. Их у меня более 3 тысяч. На каждый индекс выделяется память, кратная числу блоков (это какой-то параметр базы, я с ходу не помню).
На индекс выделяется как минимум 1 сегмент = 8 блоков, в твоём случае — 64 кб. На 3000 секций — 190 мегабайт. Что-то тут не сходится.

marat7256

Спасибо, почитаю.

marat7256

Ну, вот у меня тоже непонимание.
Проблема в том, что когда я создаю локальный индекс (уже не первый заканчивается место в табличном пространстве, которого до этого было жопой жуй. Добавляешь места, и оно заканчивается (а добавляю я сделав еще один датафайл на 32Гб). Надо, видимо, еще поковыряться.

mbolik1

Проблема в том, что когда я создаю локальный индекс (уже не первый заканчивается место в табличном пространстве, которого до этого было жопой жуй. Добавляешь места, и оно заканчивается (а добавляю я сделав еще один датафайл на 32Гб). Надо, видимо, еще поковыряться.
А можно статистику: сколько занимает табличка, какие в ней колонки и сколько занимает индекс, какие в нём колонки.
Посмортеть куда место девается можно в user_segments.
Узнать насколько используется место в сегменте таблицы/индекса: dbms_space

marat7256

2. Materialized View Тынц. — хранить предаггрегированные данные для запросов по большим периодам.
Насколько это лучше/хуже хранить предаггрегированные данные в отдельных таблицах?
То есть я понял на счет "переделки" запросов, использующих аггрегирующие функции, но у меня задача проще в том смысле, что аггрегация заранее известна и именно такие данные активно используются.

mbolik1

Насколько это лучше/хуже хранить предаггрегированные данные в отдельных таблицах?
It depends.
Хранение в отдельных таблицах точно займёт меньше места, но MV могут помочь в следующих ситуациях:
1. Пришли данные которые меняют уже рассчитанный аггрегат.
2. Запрос считается частью на аггрегате, частью на детальных данных. Например, ты считаешь результат за 3,5 месяца, а аггрегаты хранишь помесячные. С MV запрос может быть переписан на 3 аггрегированных месяца + 0.5 детальных.
+ не надо самому писать пакет аггрегации, кнопочку нажал и оно само.

marat7256

1. Пришли данные которые меняют уже рассчитанный аггрегат.
Этот вариант бывает, да.
Слушай, а за какие бабки ты бы наш кейс разобрал более подробно?
А если уж если из академического интереса, так вообще здорово. ;)

luna89

Кстати а почему оракл и вообще реляционная база данных? Есть же специальные time series database как раз для хранения всяких метрик с приборов и т.п. Там по идее все эти проблемы должны быть решены.
По-моему, тут обычные файлы могут зажечь.

YUAL

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

luna89

Надо еще key compression использовать: http://docs.oracle.com/cd/B28359_01/server.111/b28310/tables...

0000

Кстати, если в результатах запросах, обычно идет разбивка, например по областям, то имеет смысл сделать субпартицирование и по ним.
По MV: если их обновлять не "по требованию" (ON DEMAND то в авторежиме можно огрести, если данные малыми порциями поступают. Если обычно - загрузили огромный кусок, COMMIT, автообновление, то пойдет конечно.
Чтобы запросы переписывались, надо проверить, что опция для текущей сессии включена.

marat7256

Уже упоминали, посмотрю.

marat7256

Кстати, если в результатах запросах, обычно идет разбивка, например по областям, то имеет смысл сделать субпартицирование и по ним.

Этого нет.

По MV: если их обновлять не "по требованию" (ON DEMAND то в авторежиме можно огрести, если данные малыми порциями поступают. Если обычно - загрузили огромный кусок, COMMIT, автообновление, то пойдет конечно.

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

Чтобы запросы переписывались, надо проверить, что опция для текущей сессии включена.
Это понятно, да.

0000

Разумеется при массивной (BULK) загрузке данных индекс лучше отключать, как и например FK, если есть.
Насколько это поможет при перестроении вьюшек не знаю, не сильно спец.
Имхо у тебя сейчас две задачи: архитектура хранения данных (разработчик) и оптимизация базы под выбранную архитектуру (админ). Быстроту выборки обычно решают через агрегаты, но обговаривают, что они обновляются, раз в час или реже. У Оракла конечно есть "онлайн"-обновления, но насколько это прямо работает еще вопрос.
Оставить комментарий
Имя или ник:
Комментарий: