Partitioneren in postgresql werkt prima voor grote logbestanden. Maak eerst de bovenliggende tabel:
create table game_history_log (
gameid integer,
views integer,
plays integer,
likes integer,
log_date date
);
Maak nu de partities aan. In dit geval zou één voor elke maand, 900 k rijen, goed zijn:
create table game_history_log_201210 (
check (log_date between '2012-10-01' and '2012-10-31')
) inherits (game_history_log);
create table game_history_log_201211 (
check (log_date between '2012-11-01' and '2012-11-30')
) inherits (game_history_log);
Let op de controlebeperkingen in elke partitie. Als u probeert in te voegen in de verkeerde partitie:
insert into game_history_log_201210 (
gameid, views, plays, likes, log_date
) values (1, 2, 3, 4, '2012-09-30');
ERROR: new row for relation "game_history_log_201210" violates check constraint "game_history_log_201210_log_date_check"
DETAIL: Failing row contains (1, 2, 3, 4, 2012-09-30).
Een van de voordelen van partitionering is dat het alleen in de juiste partitie zoekt, waardoor de zoekgrootte drastisch en consistent wordt verminderd, ongeacht hoeveel jaar aan gegevens er zijn. Hier de uitleg voor het zoeken naar een bepaalde datum:
explain
select *
from game_history_log
where log_date = date '2012-10-02';
QUERY PLAN
------------------------------------------------------------------------------------------------------
Result (cost=0.00..30.38 rows=9 width=20)
-> Append (cost=0.00..30.38 rows=9 width=20)
-> Seq Scan on game_history_log (cost=0.00..0.00 rows=1 width=20)
Filter: (log_date = '2012-10-02'::date)
-> Seq Scan on game_history_log_201210 game_history_log (cost=0.00..30.38 rows=8 width=20)
Filter: (log_date = '2012-10-02'::date)
Merk op dat behalve de bovenliggende tabel het alleen de juiste partitie heeft gescand. Het is duidelijk dat je indexen op de partities kunt hebben om een sequentiële scan te vermijden.