powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Одна большая таблица или две разных
25 сообщений из 27, страница 1 из 2
Одна большая таблица или две разных
    #38934926
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Мне нужна консультация по архитектуре.

Короткая формулировка вопроса : При SELECT по первичному ключу имеет ли значение размер таблицы?

Подробное описание проблемы :

Есть таблица на 10 Гб.

CREATE TABLE actions (
user_uni INT NOT NULL,
project_id INT NOT NULL,
action_time INT,
status SMALLINT
)


Первичный ключ составной: user_uni, project_id

Нужно постоянно проверять выполнил ли пользователь user_uni действие по проекту project_id.

Есть вариант разбить таблицу на две actions (1-2 ГБ) и actions_history (8-9 ГБ), где actions будет хранить только действия по актуальным проектам, а actions_history - действия по проектам, которые на данный момент закрыты.

Я не сомневался бы в правильности этого решения, но есть один нюанс: закрытый проект может быть открыт заново. В случае если проект будет открыт заново (а это происходит регулярно) нужно перенести данные из actions_history в actions, а это может быть от 1000 до 100000 строк. INSERT 100000 строк в одну таблицу и DELETE 100000 из другой таблицы существенная нагрузка.

Возникает вопрос: а имеет ли смысл разделение на две таблицы?

Спасибо за ваше внимание. Буду благодарен за любые советы.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934930
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
commanddotcomINSERT 100000 строк в одну таблицу и DELETE 100000 из другой таблицы существенная нагрузка.
А если произойдет сбой, то вообще беда: дубль первичного ключа и обратно данные уже не вернуться. Надо делать транзакцию и иммитировать INSERT IGNORE, а это дополнительный расход ресурсов и повышение вероятности отказа сервера.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934943
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcom,

решение с переносом кучек туда--сюда конечно негодное.

если удастся разбить партиции так, чтобы перенос в архив и обратно происходил без delete/insert (а только ALTER TABLE partXXX NO INHERIT xxx ; ALTER TABLE partXXX INHERIT yyy;) -- то возможно такое партицирование будет уместно. (хотя там есть подводный камень неприятного размера прямо в архитектуре пж -- куча запросов может в момент этого самого NO INHERIT взбрыкнуть с ошибкой. и это -- не лечится [а гурья не чешутся, и даже не собираются]).
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934964
Фотография ПЕНСИОНЕРКА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcomЕсть таблица на 10 Гб.

CREATE TABLE actions (
user_uni INT NOT NULL,
project_id INT NOT NULL,
action_time INT,
status SMALLINT
)
за счет чего 10 гигов,или это не вся структура
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934966
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ПЕНСИОНЕРКАcommanddotcomЕсть таблица на 10 Гб.

пропущено...
за счет чего 10 гигов,или это не вся структура

30 млн записей
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934986
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcom,

Можно выиграть в размере индекса, если сделать условный индекс
Предположим, что активный проект имеет статус = 0, тогда:
Код: plsql
1.
create index i_actions_active on actions (project_id,user_uni) where status = 0;


Если активных проектов мало, то выборка будет довольно эффективной
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38934995
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tadmincommanddotcom,

Можно выиграть в размере индекса, если сделать условный индекс
Предположим, что активный проект имеет статус = 0, тогда:
Код: plsql
1.
create index i_actions_active on actions (project_id,user_uni) where status = 0;


Если активных проектов мало, то выборка будет довольно эффективной

Так project_id,user_uni все равно первичный ключ. Вы его убрать предлагаете?

Развивая Вашу мысль я могу добавить поле project_status SMALLINT и в момент когда проект закрыт делать UPDATE для этого поля при изменении типа кампании на "открыт"\"закрыт". Ну, и соответственно индекс:

Код: plsql
1.
create index i_actions_active on actions (project_id,user_uni) where project_status = 0;



Запрос SELECT типа

Код: plsql
1.
SELECT * FROM actions WHERE user_uni=20 AND project_id=88 AND project_status=0



Но будет ли движек PostgreSQL использовать этот индекс, если все равно есть первичный ключ?
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935015
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcomДобрый день. Мне нужна консультация по архитектуре.

Короткая формулировка вопроса : При SELECT по первичному ключу имеет ли значение размер таблицы?

Подробное описание проблемы :

Есть таблица на 10 Гб.

CREATE TABLE actions (
user_uni INT NOT NULL,
project_id INT NOT NULL,
action_time INT,
status SMALLINT
)


Первичный ключ составной: user_uni, project_id

Нужно постоянно проверять выполнил ли пользователь user_uni действие по проекту project_id.

Есть вариант разбить таблицу на две actions (1-2 ГБ) и actions_history (8-9 ГБ), где actions будет хранить только действия по актуальным проектам, а actions_history - действия по проектам, которые на данный момент закрыты.

Я не сомневался бы в правильности этого решения, но есть один нюанс: закрытый проект может быть открыт заново. В случае если проект будет открыт заново (а это происходит регулярно) нужно перенести данные из actions_history в actions, а это может быть от 1000 до 100000 строк. INSERT 100000 строк в одну таблицу и DELETE 100000 из другой таблицы существенная нагрузка.

Возникает вопрос: а имеет ли смысл разделение на две таблицы?

Спасибо за ваше внимание. Буду благодарен за любые советы.

Мой совет - да 100% имеет смысл. Просто потому что actions на 1-2Gb будет эффективно кешироваться в памяти базы а вот общая таблица с историей - далеко не факт (и скорее всего в таблицу истории особо никто ходить не будет).
А перекинуть 100.000 строк в транзакции не такая уж большая проблема если это делается редко.


--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935255
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tadmin,

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

Первичный ключ — это в первую очередь средство контроля целостности, наличие индекса является результатом физической реализации. Он должен быть и точка.

У вас есть частый запрос, исходите от него. Если предикаты запроса высокой селективности — стройте дополнительный индекс по всем полям. Если какое-то поле малой селективности (тот же статус), то постройте частичный индекс.

PostgreSQL принимает решение о том, какой индекс выгоднее, в первую очередь исходя из размеров индекса. Гадать тут смысла нет — сделайте дамп ваших таблиц, загрузите в тестовую базу, постройте индексы, сделайте партиционирование. И сравните скорость исполнения запросов для разных решений. На основании тестов принимайте решение.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935271
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
condomotsosadom,

количество операций при доступе по btree-индексу зависит от глубины/высоты индекса, которая зависит логарифмически от количества записей.
то есть, разница 100k и 100m отсутствует или ничтожно мала. с другой стороны, не стоит игнорироавать такой фактор, как попадание страницы индекса в кеш. при интенсивной работе по всем значениям потери на невлезающем в кеш индексе будут существенны.

что же по общему подходу, для отслеживания изменений вместо периодического опроса нужно использовать нотификацию через очередь и другие push-механизмы.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935283
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovЯ поддерживаю решение с частичным индексом, я бы предпочел такое решение партиционированию....
С индексом проблемы нет. Доступ собственно к индексу должен быть примерно одинаков

А вот про саму таблицу "не все так очевидно" ( C ) дочь офицера

Встречался с ситуациями, когда приложение выбирало большое кол-во данных из таблице по индексу и, похоже, начинал влиять такой фактор как фрагментация данных в таблице. Т.е., выбираем 1000 коротких записей по конкретному пользователю, но из-за того, что они создавались в разное время и в вперемешку с чужими записями, фактически вычитываем 1000 блоков БД. Получаем 1000 случайных IO операций которые стоят колом на системе хранения.

Таблица была большая ( > 40-50 Gb) т.ч. надежды на кеширование не было + из-за той же фрагментации, фактически вся таблица была "горячая". Т.ч. никакого эффекта "будет всегда горячим, как и та часть таблицы, которую он охватывает" не было и в помине.

На Oracle вылечилось созданием мега-индекса, где были перечислены все необходимые для запроса поля. Доступ начал происходит к отсортированной информации, кол-во считывание блоков с диска для запросов упало на порядки (ускорение было в 100-ни раз, десятки минут -> секунды).

Возможно, более "грамотным" решением на Oracle были бы Index organized table или partition, но создание мега-широкого индекса показалось предпочтительнее (по тестам, индех организованные таблицы крайне странно работали с точки зрения производительности).

авторМой совет - да 100% имеет смысл. Просто потому что actions на 1-2Gb будет эффективно кешироваться в памяти базы а вот общая таблица с историей - далеко не факт (и скорее всего в таблицу истории особо никто ходить не будет).

плюсуюсь. На этом действительно можно сильно выиграть (а может и нет, все зависит от Ваших данных и запросов).
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935413
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мнения разделились... Окей, спасибо всем отписавшимся за мысли и идеи. Потестирую варианты и "будем посмотреть", как говорят в Одессе.

В истории с двумя таблицами меня больше всего целостность данных беспокоит. Первичный ключ действует в рамках таблицы. INSERT IGNORE нет. Одна строка загуляла каким-то образом (такое может быть только вследствие сбоя) не в ту таблицу и вся транзакция псу под хвост.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935441
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorov,

авторкак и та часть таблицы, которую он охватывает

Вы не учитываете один важный факт - данные делятся на горячие и холодные на уровне строк, а кеширование идет на уровне 8kb страниц. Никакого разумного метода обеспечить локализацию горячих данных в заданных страницах нет, скорее всего в этой задаче горячие строки будут раскиданы случайно по таблице (так как это не insert only таблица-лог где все свежие данные автоматом попадают в конец файла). Обычно это приводит к тому что вместо 1GB горячих данных и 10GB холодных на выходе получается 11GB холодных данных, и все работает медленно и печально.

Вообще разделение на уровне таблиц горячих(текущих) и холодных(архивных) данных там где это возможно по бизнес логике это одна из моих стандартных рекомендаций для таблиц размером больше 10GB (особенно если не использовать SSD диски).

PS: это не относится к ситуациям когда база заведомо помещается в память, хотя как правило базы растут быстрее чем память которую можно поставить в сервер и со временем всеравно начинаются обращения к диску.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38935628
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcom,

сколько проектов всего
сколько из них "активных" ?
какова частота и глубина возврата в активные ?
не просматривали сегментацию по диапазонам project_id ? (оно же-- будет чеками для планировщика).


для активации апдейтом (статуса проекта) надо отапдейтить столько же записей, как и для активации перемещением. т.ч. овчинка интересная, но выделки, похоже, не стоит.
история с перемещением тоже кривая -- нет констрайнта для планировщика -- как минимум страницу индекса истории придется поднимать . если же project_id изрядно попутаются -- то и больше. т.ч. тоже пуля из той ещё субстанции получается.
"нет в шизне щастя"
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936661
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Короткая формулировка вопроса : При SELECT по первичному ключу имеет ли значение размер таблицы?


нет, практически не имеет.

Подробное описание проблемы :

Есть таблица на 10 Гб.



Мерий таблицы не объемом в байтах, а количеством строк.





Есть вариант разбить таблицу на две actions (1-2 ГБ) и actions_history (8-9 ГБ), где actions будет хранить только действия по актуальным проектам, а actions_history - действия по проектам, которые на данный момент закрыты.



пока не вижу смысла. лучше тогда использовать партицирование по времени, разобрать на ччто то типа 100 пермский, тогда может будет толку больше...




Я не сомневался бы в правильности этого решения, но есть один нюанс: закрытый проект может быть открыт заново. В случае если проект будет открыт заново (а это происходит регулярно) нужно перенести данные из actions_history в actions, а это может быть от 1000 до 100000 строк. INSERT 100000 строк в одну таблицу и DELETE 100000 из другой таблицы существенная нагрузка.

1000 небольшая, став тысяч уже конечно хуже.

Возникает вопрос: а имеет ли смысл разделение на две таблицы?

сколько записей всего и будет в разделенных таблицах?

пока я бы не делил...
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936663
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukcommanddotcomДобрый день. Мне нужна консультация по архитектуре.

Короткая формулировка вопроса : При SELECT по первичному ключу имеет ли значение размер таблицы?

Подробное описание проблемы :

Есть таблица на 10 Гб.

пропущено...


Первичный ключ составной: user_uni, project_id

Нужно постоянно проверять выполнил ли пользователь user_uni действие по проекту project_id.

Есть вариант разбить таблицу на две actions (1-2 ГБ) и actions_history (8-9 ГБ), где actions будет хранить только действия по актуальным проектам, а actions_history - действия по проектам, которые на данный момент закрыты.

Я не сомневался бы в правильности этого решения, но есть один нюанс: закрытый проект может быть открыт заново. В случае если проект будет открыт заново (а это происходит регулярно) нужно перенести данные из actions_history в actions, а это может быть от 1000 до 100000 строк. INSERT 100000 строк в одну таблицу и DELETE 100000 из другой таблицы существенная нагрузка.

Возникает вопрос: а имеет ли смысл разделение на две таблицы?

Спасибо за ваше внимание. Буду благодарен за любые советы.

Мой совет - да 100% имеет смысл. Просто потому что actions на 1-2Gb будет эффективно кешироваться в памяти базы а вот общая таблица с историей - далеко не факт (и скорее всего в таблицу истории особо никто ходить не будет).
А перекинуть 100.000 строк в транзакции не такая уж большая проблема если это делается редко.


--
Maxim Boguk
www.postgresql-consulting.ru

Максим, так части одной таблицы тоже будут эффективно кэшироваться в памяти, нужные оставаться, ненужные уходить...
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936666
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorov,
PostgreSQL принимает решение о том, какой индекс выгоднее, в первую очередь исходя из размеров индекса.

это не так.
не из размера индекса, а из его селективности по данному условию.
т.е. индекс может быть и большой, но если он отбирает 1 запись из 30 миллионов, он будет использоваться.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936676
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcomПЕНСИОНЕРКАпропущено...
за счет чего 10 гигов,или это не вся структура

30 млн записей

это не очень и много, пробуй пока так, без партицирования и без разделения на две таблицы.

фактор кэширования конечно важен, но не настолько, чтобы быть решающим. решающий фактор - использование индексов.

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

пока немного смущает, что таблица узкая, а записей в ней много...
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936679
Фотография ПЕНСИОНЕРКА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivпока немного смущает, что таблица узкая, а записей в ней много...

меня тоже смутило именно это, что сама узкая таблица информации по-сути не несет
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936680
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
commanddotcom,

CREATE TABLE actions (
user_uni INT NOT NULL,
project_id INT NOT NULL,
action_time INT,
status SMALLINT
)

- ну странная таблица....


атрибутов мало, почему action_time - целое число?
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936798
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivМаксим, так части одной таблицы тоже будут эффективно кэшироваться в памяти, нужные оставаться, ненужные уходить...

Кешируется вся страница 8kb целиком а не отдельные строки. При вышеописанном режиме использования скорее всего на средней 8kb странице в таблице будет 10% нужных данных и 90% архивных (так как я не вижу ни одной причины почему бы не-архивным данным как то кластеризоваться на уровне страниц данных). Собственно деление таблицы на две как раз призвано устранить эту неэффективность в таком случае.


--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936908
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukMasterZivМаксим, так части одной таблицы тоже будут эффективно кэшироваться в памяти, нужные оставаться, ненужные уходить...
При вышеописанном режиме использования скорее всего на средней 8kb странице в таблице будет 10% нужных данных и 90% архивных (так как я не вижу ни одной причины почему бы не-архивным данным как то кластеризоваться на уровне страниц данных). Собственно деление таблицы на две как раз призвано устранить эту неэффективность в таком случае.
А может периодический CLUSTER тут поможет?
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38936984
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovMaxim Bogukпропущено...

При вышеописанном режиме использования скорее всего на средней 8kb странице в таблице будет 10% нужных данных и 90% архивных (так как я не вижу ни одной причины почему бы не-архивным данным как то кластеризоваться на уровне страниц данных). Собственно деление таблицы на две как раз призвано устранить эту неэффективность в таком случае.
А может периодический CLUSTER тут поможет?

cluster упорядочивает данные в порядке индекса, так что да при правильном выборе индекса cluster поможет.
Я бы сказал надо cluster по (project_id) если его делать достаточно часто (достаточно - определяется тем насколько много в таблицу пишут нового и насколько часто ее обновляют).
Но CLUSTER намертво блокирует таблицу на время работы.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38937126
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovА может периодический CLUSTER тут поможет?
CLUSTER не подходит, я думаю. Постоянно идет запись.

MasterZivпока немного смущает, что таблица узкая, а записей в ней много...

атрибутов мало, почему action_time - целое число?

1) Обычная таблица отношений "многие ко многим". Не вижу ничего странного.
2) По action_time выборки нет и не будет. Вот такой я человек - храню время в unixtimestamp.

---

Если кому интересно на чем я остановился:

Сравнил это 17508603 решение и разделение на две таблицы. При разделении на две таблицы расход ОЗУ меньше почти в 10 раз, но со скачками при переносе данных из таблицы в таблицу. В общем, решил остановиться пока на этом варианте. Перенос обернул в транзакцию и на всякий случай заранее написал утил для восстановление целостности первичного ключа на случай сбоя.
...
Рейтинг: 0 / 0
Одна большая таблица или две разных
    #38937141
commanddotcom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
P.S. Имитировать INSERT IGNORE (делать проверку на наличие ключа перед переносом строки) не стал. Если будут сбои, то пусть я о них узнаю раньше, чем прикрывать срам фиговым листом.
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Одна большая таблица или две разных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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