Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Уникальность на сегментированной таблице, PostgreSQL partition 
V
    Опции темы
Paher
Дата 17.9.2013, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 18.8.2009

Репутация: нет
Всего: нет



Доброго здоровья, уважаемые!

Есть у меня в PostgreSQL базе таблица с миллионами строк. Для ускорения решил применить ее сегментирование(партицирование). Разделял по полю "date" по месяцам. Сделал следующее:

таблица с триггером
Код

CREATE TABLE "public"."packages" ( 
    "id" INTEGER NOT NULL UNIQUE, 
    "date" TIMESTAMP WITHOUT TIME ZONE, 
    "uid" CHARACTER VARYING( 32 ), 
    "filename" CHARACTER VARYING( 255 ), 
         PRIMARY KEY ( "id" ),        
         CONSTRAINT "uid_key" UNIQUE( "uid" ) 
);
CREATE TRIGGER server_master_trigger BEFORE INSERT ON "public"."packages" FOR EACH ROW EXECUTE PROCEDURE server_partition_function();


функция на триггере
Код

CREATE OR REPLACE FUNCTION public.server_partition_function()
    RETURNS TRIGGER
    LANGUAGE plpgsql
    AS $function$
        DECLARE
            
            _tablename text;
            _suffix text;
            _pattern text;
            _begindate date;
            _enddate date;
            _check text;
            _query text;

        BEGIN
  
            _pattern := 'YYYY_MM';
            _suffix := to_char(NEW."send_date", _pattern);
            _tablename := 'packages_' || _suffix;
            _begindate := CAST(_suffix || '-01' as date);
            _enddate := _begindate + interval '1 month';
            _check := FORMAT('%s BETWEEN %s AND %s', quote_literal(NEW."send_date"), quote_literal(_begindate), quote_literal(_enddate));
            _query := FORMAT('INSERT INTO %s  VALUES (%s, $1.date, $1.uid, $1.filename)', _tablename, nextval('user_id_seq'));
  
                  BEGIN
                        EXECUTE _query USING NEW;
                  EXCEPTION 
                        WHEN undefined_table THEN
                              EXECUTE FORMAT('CREATE TABLE IF NOT EXISTS %s (
                                                                    CHECK (%s),
                                                                    CONSTRAINT "uid_%s" UNIQUE( "uid"),
                                                                    PRIMARY KEY ("id")     
                                                             ) INHERITS ("packages")', _tablename, _check, _suffix);  
    
      
                              EXECUTE _query USING NEW;
      
                  END;
             RETURN NULL;
        END;
   $function$



Собственно, вопроса два. 

1) для самоуспокоения и просвещения. Во всех примерах в гугле динамические таблицы создаются после проверки их на существование. Я сделал через обработку исключения. На мой взгляд выгода в моем варианте в том, что при уже существующей таблице строка в нее записывается сразу, без проверки ее существования. Однако, возможно тут есть какие-то подводные камни, о которых я не знаю(например, затраты на возбуждение и обработку исключения болььше, чем проверка таблицы на существование). Просьба на них указать. 
2) практический вопрос. Никак не получается сделать уникальным поле "uid" в рамках таблицы "packages". Получается только на каждой партиции. Возможно ли это, и если да, то как?
PM MAIL   Вверх
Zloxa
Дата 18.9.2013, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Paher @  18.9.2013,  00:03 Найти цитируемый пост)
функция на триггере

И как оно ваще - работает?
Интересуюсь потому что знаком с ПГ лишь понаслышке.

DDL должен бы коммитить транзакцию, а триггер должен бы работать в пределах транзакции. Известные мне системы не позволяют завершать транзакцию в теле триггера.

Ну и вобще DDL в прикладной логике это моветон.

PS Почитал, оказывается в PG действительно с секционированием тоска-тоска smile

Цитата(Paher @  18.9.2013,  00:03 Найти цитируемый пост)
 Возможно ли это, и если да, то как? 

Походу - нет. Ответ на столько же очевиден, насколько легко гуглится

Цитата(Paher @  18.9.2013,  00:03 Найти цитируемый пост)
Для ускорения

А что ускоряете то?
Быть может оно вам и в пень не вдулось. Секционирование добавляет перфомансу в весьма специфических случаях.  В общем случае, оно скорее его уменьшает.

Это сообщение отредактировал(а) Zloxa - 18.9.2013, 00:18


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Paher
Дата 18.9.2013, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 18.8.2009

Репутация: нет
Всего: нет



Цитата(Zloxa @  18.9.2013,  00:05 Найти цитируемый пост)
И как оно ваще - работает?

Работает, подтаблицы создаются, данные читаются 

Цитата(Zloxa @  18.9.2013,  00:05 Найти цитируемый пост)
Походу - нет. Ответ на столько же очевиден, насколько легко гуглится

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

Цитата(Zloxa @  18.9.2013,  00:05 Найти цитируемый пост)
А что ускоряете то?

насколько я понимаю, секционирование ускоряет чтение на больших таблицах. В данном случае, если мне нужны сведения только за пару месяцев, то база и 
будет их искать только в 2 маленьких подтаблицах, а не лопатить все миллионы записей. В некоторых случаях даже получается перебор подтаблицы быстрее, чем поиск по индексу.
Конечно, есть какой-то оверхед на проверку условий при записи(это в моем случае терпимо) и при чтении(в этом случае ускорение от партицирования должно превышать оверхед).  Это в теории. На практике сейчас и хочу это проверить

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

Это сообщение отредактировал(а) Paher - 18.9.2013, 09:24
PM MAIL   Вверх
Zloxa
Дата 18.9.2013, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Paher @  18.9.2013,  10:04 Найти цитируемый пост)
Работает, подтаблицы создаются, данные читаются 

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

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

Цитата(Paher @  18.9.2013,  10:04 Найти цитируемый пост)
Не могли бы подсказать для дураков?

Повторяю.
Цитата(Zloxa @  18.9.2013,  01:05 Найти цитируемый пост)
нет


Цитата(Paher @  18.9.2013,  10:04 Найти цитируемый пост)
насколько я понимаю, секционирование ускоряет чтение на больших таблицах.

не всякое чтение.
Цитата(Paher @  18.9.2013,  10:04 Найти цитируемый пост)
В данном случае, если мне нужны сведения только за пару месяцев, то база и 
будет их искать только в 2 маленьких подтаблицах, а не лопатить все миллионы записей.

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

Это сообщение отредактировал(а) Zloxa - 18.9.2013, 09:57


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Paher
Дата 18.9.2013, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 18.8.2009

Репутация: нет
Всего: нет



Цитата(Zloxa @  18.9.2013,  09:56 Найти цитируемый пост)
что с транзакцией? Транзакцию триггер при создании новой таблицы рвет?

Если я правильно понял вопрос, то не рвет, транзакции работают правильно, с полным откатом по ROLLBACK

Цитата(Zloxa @  18.9.2013,  09:56 Найти цитируемый пост)
Обычно в этих случаях секции нарезают впрок.

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

 
Цитата(Zloxa @  18.9.2013,  09:56 Найти цитируемый пост)
Повторяю.
Цитата(Zloxa @  18.9.2013,  01:05 )
нет

тут вопрос был уже не в том, можно ли, а в том, где найти обяснение, почему нельзя, ведь 
Цитата(Zloxa @  18.9.2013,  00:05 Найти цитируемый пост)
Ответ на столько же очевиден, насколько легко гуглится
 для меня не так очевиден

Цитата(Zloxa @  18.9.2013,  09:56 Найти цитируемый пост)
До определенного предела. Если у вас в выборке используются все данные по одному - двум месяцам, это действительно может дать профит. Но профиту будет тем меньше, чем больше месяцев попадает в эти выборки. Полный фулскан будет иметь оверхед. Межсекционный отбор, скажем, по товару, будет иметь существенный оверхед, даже если отбор идет по индексам.

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


Это сообщение отредактировал(а) Paher - 18.9.2013, 11:05
PM MAIL   Вверх
Zloxa
Дата 18.9.2013, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Paher @  18.9.2013,  12:00 Найти цитируемый пост)
Если я правильно понял вопрос, то не рвет, транзакции работают правильно, с полным откатом по ROLLBACK

Я правильно понимаю что это означеат, что PG создает новую таблицу либо в контексте текущей транзакции, либо в автономной? Если так, пожалуй стоит забрать ранее выставленный минус в карму smile

Цитата(Paher @  18.9.2013,  12:00 Найти цитируемый пост)
вряд ли получится предсказать, когда проект умрет и сколько надо сделать секций.

По этой причине определяют регламент проведения технических работ в рамках которого донарезаются секции.

Цитата(Paher @  18.9.2013,  12:00 Найти цитируемый пост)
почему нельзя

Потому что индекс может обеспечивать уникальность лишь в пределах таблицы же.

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


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Paher
Дата 18.9.2013, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 18.8.2009

Репутация: нет
Всего: нет



Цитата(Zloxa @  18.9.2013,  11:39 Найти цитируемый пост)
По этой причине определяют регламент проведения технических работ в рамках которого донарезаются секции.

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



Цитата(Zloxa @  18.9.2013,  11:39 Найти цитируемый пост)
На сколкьо я понял из документации, секционирования как такового в ПГ не реализовано. Документация предлагает некий воркэраунд, который с помощью подручных, не в первую очередь для того предназначенных средств, позволяет воспроизвести эффект близкий к эффекту секционирования.  

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


Цитата(Zloxa @  18.9.2013,  11:39 Найти цитируемый пост)
Глобального индексирования с помощью приведенных средств добиться нельзя, о чем в документации указанно явно. 

за это огромное спасибо, что-то я это проворонил

Это сообщение отредактировал(а) Paher - 18.9.2013, 12:37
PM MAIL   Вверх
Zloxa
Дата 18.9.2013, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Zloxa @  18.9.2013,  12:39 Найти цитируемый пост)
это означеат, что PG создает новую таблицу либо в контексте текущей транзакции

Походу так и есть(и тут, похоже только оракля нот суппорт транзакшнал ДДЛ). Таки тут плюс в карму постгру. В документации на сей счет, правда, чойта не могу нагуглить. smile

Цитата(Paher @  18.9.2013,  12:53 Найти цитируемый пост)
Секционирование реализовано частично, например, чтение  из секционированной таблицы не требует плясок с бубнами. А вот с записью - да, приходится костылей написывать 

Секционирование не реализовано. Реализовано наследование, ограниченное исполнение, триггеры, правила, средствами которых можно добиться функционала близкого к функционалу секционирования smile

Это сообщение отредактировал(а) Zloxa - 18.9.2013, 17:24


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0491 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.