Re: Why creating GIN table index is so slow than inserting data into empty table with the same index?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sergey Burladyan <eshkinkot@xxxxxxxxx> writes:
> show maintenance_work_mem ;
>  maintenance_work_mem
> ----------------------
>  128MB

> create table a (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int);
> insert into a select n, n, n, n, n, n from generate_series(1, 100000) as n;
> create index arr_gin on a using gin ( (array[i1, i2, i3, i4, i5, i6]) );

[ takes forever ]

Seems the reason this is so awful is that the incoming data is exactly
presorted, meaning that the tree structure that ginInsertEntry() is
trying to build degenerates to a linear list (ie, every new element
becomes the right child of the prior one).  So the processing becomes
O(N^2) up till you reach maintenance_work_mem and flush the tree.  With
a large setting for maintenance_work_mem it gets spectacularly slow.

I think a reasonable solution for this might be to keep an eye on
maxdepth and force a flush if that gets too large (more than a few
hundred, perhaps?).  Something like this:

    /* If we've maxed out our available memory, dump everything to the index */
+   /* Also dump if the tree seems to be getting too unbalanced */
-   if (buildstate->accum.allocatedMemory >= maintenance_work_mem * 1024L)
+   if (buildstate->accum.allocatedMemory >= maintenance_work_mem * 1024L ||
+       buildstate->accum.maxdepth > DEPTH_LIMIT)
    {

The new fast-insert code likely will need a similar defense.

Comments?

			regards, tom lane

-- 
Sent via pgsql-performance mailing list (pgsql-performance@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux