Обсуждение: delete/recreate indexes

Поиск
Список
Период
Сортировка

delete/recreate indexes

От
alan
Дата:
Hi

I'm a postgres novice so ....

I have this fairly simple table
-------------------------------------------------
 device integer not null,
 group integer not null,
 datum timestamp without time zone not null,
 val1 numeric(7,4) not null default 0.000,
 val2 numeric(7,4) not null default 0.000
-------------------------------------------------

The device column is a foreign-key to the PK of my device table.
and I have a UNIQUE INDEX on 3 columns device, group, datum

This is just a test database and I want to keep the "datum" values
(timestamps that span approx 1 month) all bound to CURRENT_DATE().

So I thought I’d just run this once (via cron) every morning.
    BEGIN;
        DROP INDEX data_unique;
        UPDATE data SET datum = (data.datum + interval '24 hours');
        CREATE UNIQUE INDEX data_unique ON public.data USING BTREE
(device, group, datum);
    COMMIT;

But
1.    it’s taking forever and
2.    I’m seeing that my disk is filling up real fast.

Any suggestions?

Alan

Re: delete/recreate indexes

От
Jeff Davis
Дата:
On Wed, 2011-10-19 at 08:03 -0700, alan wrote:
> So I thought I’d just run this once (via cron) every morning.
>     BEGIN;
>         DROP INDEX data_unique;
>         UPDATE data SET datum = (data.datum + interval '24 hours');
>         CREATE UNIQUE INDEX data_unique ON public.data USING BTREE
> (device, group, datum);
>     COMMIT;
>
> But
> 1.    it’s taking forever and
> 2.    I’m seeing that my disk is filling up real fast.

An unrestricted update will end up rewriting the whole table. It's
advisable to run VACUUM afterward, so that the wasted space can be
reclaimed. What version are you on? Do you have autovacuum enabled?

Also, to take a step back, why do you try to keep the timestamps
changing like that? Why not store the information you need in the record
(e.g. insert time as well as the datum) and then compute the result you
need using a SELECT (or make it a view for convenience)? Fundamentally,
these records aren't changing, you are just trying to interpret them in
the context of the current day. That should be done using a SELECT, not
an UPDATE.

Regards,
    Jeff Davis



Re: delete/recreate indexes

От
"Bort, Paul"
Дата:
> An unrestricted update will end up rewriting the whole table. 
> It's advisable to run VACUUM afterward, so that the wasted 
> space can be reclaimed. What version are you on? Do you have 
> autovacuum enabled?
> 
> Also, to take a step back, why do you try to keep the 
> timestamps changing like that? Why not store the information 
> you need in the record (e.g. insert time as well as the 
> datum) and then compute the result you need using a SELECT 
> (or make it a view for convenience)? Fundamentally, these 
> records aren't changing, you are just trying to interpret 
> them in the context of the current day. That should be done 
> using a SELECT, not an UPDATE.
> 

I like Jeff's idea of redefining the problem. If you need the data to contain dates in the last 30 days, you might want
toconsider storing an interval, then using a view that includes a calculation using CURRENT_DATE().
 

Regards,
Paul Bort
Systems Engineer
TMW Systems, Inc.
pbort@tmwsystems.com
216 831 6606 x2233
216 8313606 (fax)


Re: delete/recreate indexes

От
alan
Дата:
Thanks Jeff,

On Oct 20, 4:51 am, pg...@j-davis.com (Jeff Davis) wrote:
> Also, to take a step back, why do you try to keep the timestamps
> changing like that? Why not store the information you need in the record
> (e.g. insert time as well as the datum) and then compute the result you
> need using a SELECT (or make it a view for convenience)? Fundamentally,
> these records aren't changing, you are just trying to interpret them in
> the context of the current day. That should be done using a SELECT, not
> an UPDATE.

Well this is not the way my "production" table is getting updated.
This was a developer's test DB so I thought the update statement would
be a
quick way to just shift all the values.

To mimic how my "production" database is being updated I should be
doing
this once each morning:

    1. delete the old entries older than 6 days (i.e.: my table holds
one week's data)
    2. add new entries for yesterday

I'm doing this via a perl script. For 1. I just do a
DELETE FROM device WHERE datum < (CURRENT_DATE - interval ' 7 days' )

For 2. I tried this but I get  an "invalid input syntax for type
timestamp:" error:
    my $val1 = rand(100);
    my $val2 = rand(100);
    my $stmt = "INSERT INTO data (device,group,datum,val1,val2)
VALUES(?,?,?,?,?)";
        my $insert = $dbh->prepare($stmt) or die $dbh->errstr;
    my $timestamp = "TO_TIMESTAMP(text(CURRENT_DATE - interval '1
day'),'YYYY-MM-DD HH24:MI:SS')";
    $insert->execute($device,$groupid,$timestamp,$val1,$val2));

Alan