Re: [PATCHES] [HACKERS] HOT WIP Patch - version 2

2007-02-22 Thread Jim C. Nasby
There's a fair amount of added work to be done when updating tuples.
Will it be possible to postpone some of that to the bgwriter in a later
version? I realize that sometimes you'll still want to do the work up
front, like if it means we can stay on the same page instead of going
cold...

On Tue, Feb 20, 2007 at 12:08:14PM +0530, Pavan Deolasee wrote:
> Reposting - looks like the message did not get through in the first
> attempt. My apologies if multiple copies are received.
> 
> 
> This is the next version of the HOT WIP patch. Since the last patch that
> I sent out, I have implemented the HOT-update chain pruning mechanism.
> 
> When following a HOT-update chain from the index fetch, if we notice that
> the root tuple is dead and it is HOT-updated, we try to prune the chain to
> the smallest possible length. To do that, the share lock is upgraded to an
> exclusive lock and the tuple chain is followed till we find a
> live/recently-dead
> tuple. At that point, the root t_ctid is made point to that tuple. In order
> to
> preserve the xmax/xmin chain, the xmax of the root tuple is also updated
> to xmin of the found tuple. Since this xmax is also < RecentGlobalXmin
> and is a committed transaction, the visibility of the root tuple still
> remains
> the same.
> 
> The intermediate heap-only tuples are  removed from the HOT-update chain.
> The HOT-updated status of these tuples is cleared and their respective
> t_ctid are made point to themselves. These tuples are not reachable now
> and ready for vacuuming. This entire action is logged in a single
> WAL record.
> 
> During vacuuming, we keep track of number of root tuples vacuumed.
> If this count is zero, then the index cleanup step is skipped. This
> would avoid unnecessary index scans whenever possible.
> 
> This patch should apply cleanly on current CVS head and pass all regression
> tests. I am still looking for review comments from the first WIP patch. If
> anyone
> has already looked through it and is interested in the incremental changes,
> please let me know. I can post that.
> 
> Whats Next ?
> -
> 
> ISTM that  the basic  HOT-updates and ability to prune the HOT-update chain,
> 
> should help us reduce the index bloat, limit the overhead of ctid following
> in
> index fetch and efficiently vacuum heap-only tuples. IMO the next important
> but rather less troublesome thing to tackle is to reuse space within a block
> 
> without complete vacuum of the table. This would help us do much more
> HOT-updates and thus further reduce index/heap bloat.
> 
> I am thinking of reusing the DEAD heap-only tuples which gets removed from
> the HOT-update chain as part of pruning operation. Since these tuples, once
> removed from the chain, are neither reachable nor have any index references,
> could be readily used for storing newer versions of the same or other rows
> in
> the block. How about setting LP_DELETE on these tuples as part of the
> prune operation ? LP_DELETE is unused for heap tuples, if I am not
> mistaken. Other information like length and offset are is maintained as it
> is.
> When we run out space for update-within-the-block, we traverse
> through all the line pointers looking for LP_DELETEd items. If any of these
> items have space large enough to store the new tuple, that item is reused.
> Does anyone see any issue with doing this ? Also, any suggestions
> about doing it in a better way ?
> 
> If the page gets really fragmented, we can try to grab a VACUUM-strength
> lock on the page and de-fragment it. The lock is tried conditionally to
> avoid
> any deadlocks. This is done in the heap_update() code path, so would add
> some overhead, but may still prove better than putting the tuple in a
> different block and having corresponding index insert(s). Also, since we are
> more concerned about the large tables, the chances of being able to upgrade
> the exclusive lock to vacuum-strength lock are high. Comments ?
> 
> If there are no objections, I am planning to work on the first part
> while Nikhil would take up the second task of block level retail-vacuum.
> Your comments on these issues and the patch are really appreciated.
> 
> Thanks,
> Pavan
> 
> -- 
> 
> EnterpriseDB http://www.enterprisedb.com


> 
> ---(end of broadcast)---
> TIP 2: Don't 'kill -9' the postmaster


-- 
Jim Nasby[EMAIL PROTECTED]
EnterpriseDB  http://enterprisedb.com  512.569.9461 (cell)

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] Fast CLUSTER

2007-02-22 Thread Simon Riggs
On Tue, 2007-02-20 at 14:38 -0300, Alvaro Herrera wrote:

> Cool.  I noticed that the SGML seems broken here:

Corrected. 

> You need to close the  and  opened in the COPY mention.
> 
> > + 
> > + static void
> > + heap_sync_relation(Relation rel)
> > + {
> > +   if (!rel->rd_istemp)
> 
> No comment in this function?

I've added more comments as you suggest.

Thanks for the review.

-- 
  Simon Riggs 
  EnterpriseDB   http://www.enterprisedb.com

Index: doc/src/sgml/perform.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/perform.sgml,v
retrieving revision 1.63
diff -c -r1.63 perform.sgml
*** doc/src/sgml/perform.sgml	1 Feb 2007 19:10:24 -	1.63
--- doc/src/sgml/perform.sgml	22 Feb 2007 11:50:58 -
***
*** 908,919 
  will perform more slowly when archive_command
  is set, as a result of their needing to write large amounts of WAL.
  This applies to the following commands: 
! CREATE TABLE AS SELECT, 
! CREATE INDEX and also COPY, when
! it is executed in the same transaction as a prior 
! CREATE TABLE or TRUNCATE command.
!
! 

  

--- 908,928 
  will perform more slowly when archive_command
  is set, as a result of their needing to write large amounts of WAL.
  This applies to the following commands: 
! 
!  CREATE TABLE AS SELECT
!  CREATE INDEX
!  ALTER TABLE SET TABLESPACE
!  CLUSTER
!  
!   COPY, when it is executed after one of
! 	  these commands, yet in the same transaction:
! 	  
! 	   CREATE TABLE
! 	   TRUNCATE
! 	  
!   
!  
!   

  

***
*** 950,964 
  By default, pg_dump uses COPY, and when
  it is generating a complete schema-and-data dump, it is careful to
  load data before creating indexes and foreign keys.  So in this case
! the first several guidelines are handled automatically.  What is left
! for you to do is to set appropriate (i.e., larger than normal) values
! for maintenance_work_mem and
! checkpoint_segments, as well as unsetting 
! archive_command before loading the dump script,
! and then to run ANALYZE afterwards and resetting
! archive_command if required. All of the 
! parameters can be reset once the load has completed without needing
! to restart the server, as described in .
 
  
 
--- 959,992 
  By default, pg_dump uses COPY, and when
  it is generating a complete schema-and-data dump, it is careful to
  load data before creating indexes and foreign keys.  So in this case
! several guidelines are handled automatically.  What is left
! for you to do is to:
! 
!  Set appropriate (i.e., larger than normal) values
!   for maintenance_work_mem and
!   checkpoint_segments.
!  Unset archive_command before
! 	  loading the dump script, and then reset 
! 	  archive_command afterwards, if required.
! 	 
!  
! 	  
!Consider whether the whole dump can be restored as a single
! 	   transaction, so that COPY commands can be optimized. Remember that
! 	   this will mean that all restore commands will either fully completed
! 	   or fully rolled back. This mode can be specified by passing the 
! 	   -1 or --single-transaction command-line options
! 	   to psql or pg_restore. When using this
! 	   mode, be aware that even the smallest of errors can rollback a
!restore that has already run for many hours. However, that might
!still be preferable to manually cleaning up a complex database
!after a partially restored dump.
! 	  
! 	 
!  Run ANALYZE afterwards.
! 	All of the above mentioned parameters can be reset once the load has
! 	completed without needing to restart the server, as described in 
! 	.
 
  
 
Index: src/backend/access/heap/heapam.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.228
diff -c -r1.228 heapam.c
*** src/backend/access/heap/heapam.c	9 Feb 2007 03:35:33 -	1.228
--- src/backend/access/heap/heapam.c	22 Feb 2007 11:51:00 -
***
*** 60,65 
--- 60,66 
  
  static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
  		   ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
+ static void heap_sync_relation(Relation rel);
  
  
  /* 
***
*** 3991,3996 
--- 3992,4003 
  /* 
   *		heap_sync - sync a heap, for use when no WAL has been written
   *
+  * 		Will sync all relations associated with the main table,
+  *		i.e. the main heap, indexes, the toast relation and its index
+  *		If new relation types were added, this would need extension
+  *		XXX Indexes are mentioned because its possible in the future that
+  *		we may choose to avoid writing WAL for inde

Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Guillaume Smet

On 2/22/07, Oleg Bartunov  wrote:

You're right, it would be nice.
This is what we need for faster ranking in tsearch2, since currently we should
consult heap to get positional information, which slowdowns search.
We didn't investigate the possibility to keep additional information with
index, but keep in mind, that everything should works without index.


OK, thanks for your answer. If you do it one day or another, please
take into account the case of pg_trgm too as it will be far faster if
we can access to the number of entries of the indexed value in the
consistent function. As this information is available if you don't use
the index, it won't be a problem, I think.

Is there anything else I should fix/improve in this patch?

It could be nice to test it on other distribution of words and see if
it performs better than gist in other cases too. I'll try to test it
here on another table we need to index with tsearch2.

--
Guillaume

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


[PATCHES] lo_truncate

2007-02-22 Thread Kris Jurka


The attached patch implements lo_truncate for truncating large objects to 
a given length.  This is required for implementing Blob.truncate in the 
JDBC driver[1] and rounds out filesystem like functionality for large 
objects.


Kris Jurka

[1] http://java.sun.com/javase/6/docs/api/java/sql/Blob.html#truncate(long)Index: doc/src/sgml/lobj.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/lobj.sgml,v
retrieving revision 1.44
diff -c -r1.44 lobj.sgml
*** doc/src/sgml/lobj.sgml  1 Feb 2007 19:10:24 -   1.44
--- doc/src/sgml/lobj.sgml  22 Feb 2007 20:43:16 -
***
*** 302,307 
--- 302,338 
  
  
  
+ Truncating a Large Object
+ 
+ 
+  To truncate a large object to a given length, call
+ 
+ int lo_truncate(PGcon *conn, int fd, size_t len);
+ 
+  lo_truncate truncates the large object
+  descriptor fd to length len.  The
+  fd argument must have been returned by a
+  previous lo_open.  If len is
+  greater than the current large object length, the large object
+  is extended with null bytes ('\0').
+ 
+ 
+ 
+  The file offset is not changed.
+ 
+ 
+ 
+  On success lo_truncate returns
+  zero.  On error, the return value is negative.
+ 
+ 
+ 
+  lo_truncate is new as of 
PostgreSQL
+  8.3; if this function is run against an older server version, it will
+  fail and return a negative value.
+ 
+ 
+ 
  Closing a Large Object Descriptor
  
  
Index: src/backend/libpq/be-fsstubs.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v
retrieving revision 1.84
diff -c -r1.84 be-fsstubs.c
*** src/backend/libpq/be-fsstubs.c  5 Jan 2007 22:19:29 -   1.84
--- src/backend/libpq/be-fsstubs.c  22 Feb 2007 20:43:17 -
***
*** 120,131 
int32   fd = PG_GETARG_INT32(0);
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
-   {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
!   PG_RETURN_INT32(-1);
!   }
  #if FSDB
elog(DEBUG4, "lo_close(%d)", fd);
  #endif
--- 120,129 
int32   fd = PG_GETARG_INT32(0);
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
! 
  #if FSDB
elog(DEBUG4, "lo_close(%d)", fd);
  #endif
***
*** 152,163 
int status;
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
-   {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
-   return -1;
-   }
  
status = inv_read(cookies[fd], buf, len);
  
--- 150,158 
***
*** 170,181 
int status;
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
-   {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
-   return -1;
-   }
  
if ((cookies[fd]->flags & IFS_WRLOCK) == 0)
ereport(ERROR,
--- 165,173 
***
*** 198,209 
int status;
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
-   {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
-   PG_RETURN_INT32(-1);
-   }
  
status = inv_seek(cookies[fd], offset, whence);
  
--- 190,198 
***
*** 248,259 
int32   fd = PG_GETARG_INT32(0);
  
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
-   {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
 errmsg("invalid large-object descriptor: %d", 
fd)));
-   PG_RETURN_INT32(-1);
-   }
  
PG_RETURN_INT32(inv_tell(cookies[fd]));
  }
--- 237,245 
***
*** 468,473 
--- 454,479 
  }
  
  /*
+  * lo_truncate -
+  *  truncate a large object to a specified length
+  */
+ Datum
+ lo_truncate(PG_FUNCTION_ARGS)
+ {
+   int32   fd = PG_GETARG_INT32(0);
+   int32   len = PG_GETARG_INT32(1);
+ 
+   if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
+   ereport(ERROR,
+   (e

[PATCHES] Short varlena headers

2007-02-22 Thread Gregory Stark

I've tried repeatedly to send this patch but it doesn't seem to be getting
through. It's not in the archives or my inbox. Now that I look I realized that
none of the WIP versions of the patch that I sent arrived either. That's
fairly disappointing since I had made efforts to keep people apprised of the
development.

Here's a working patch that provides 1-byte headers and unaligned storage for
varlena data types storing < 128 bytes (actually <= 126 bytes).

 http://community.enterprisedb.com/varlena/patch-varvarlena-9.patch.gz


Things it does:

1) Changes the varlena api to use SET_VARSIZE instead of VARATT_SIZEP

2) Changes the heap_form_tuple api in a subtle way: attributes in a heap tuple
   may need to be detoasted even if the tuple is never written out to disk.

3) Changes the GETSTRUCT api in another subtle way: it's no loner safe to
   access then first varlena in a tuple directly through the GETSTRUCT
   interface. At least not unless special care is taken.

4) Saves a *ton* of space because it saves 3 of the 4 bytes of varlena
   overhead *and* the up to 4 bytes of alignment padding before every varlena.
   That turns out to be a lot more space than I realized. I'll post some
   sample schemas with space savings later.

5) Passes all postgres regression tests. 

Things it doesn't do:

1) 2-byte headers for objects that exceed 128 bytes :(

2) 0-byte headers for single ascii characters :(

3) avoid htonl/ntohl by using low order bits on little-endian machines

4) provide an escape hatch for types or columns that don't want this
   behaviour. Currently int2vector and oidvector are specifically exempted
   since they're used in the system tables, sometimes through the GETSTRUCT
   api. I doubt anything not used in the system tables has any business being
   exempted which only leaves us with the occasional text attribute which I
   plan to double check aren't problems.


-- 
  Gregory Stark
  EnterpriseDB  http://www.enterprisedb.com

---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

http://www.postgresql.org/about/donate


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Teodor Sigaev



I think it can be interesting for other flavours of GIN usage. Is
there a way to add the number of entries of the considered indexed
item to the consistent prototype without adding too much overhead and
complexity?

We are thinking about adding extra value, but it's still only thinking.

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Oleg Bartunov

On Thu, 22 Feb 2007, Guillaume Smet wrote:


On 2/22/07, Teodor Sigaev <[EMAIL PROTECTED]> wrote:

How long is average length of strings in table?


test=# SELECT MIN(length(word)), MAX(length(word)), AVG(length(word))
FROM lieu_mots_gin;
min | max |avg
-+-+
 1 |  38 | 7.4615463141373282
(1 row)

I don't see how to have a more precise similarity without having the
number of entries registered by the indexed value somewhere.

I think it can be interesting for other flavours of GIN usage. Is
there a way to add the number of entries of the considered indexed
item to the consistent prototype without adding too much overhead and
complexity?


You're right, it would be nice.
This is what we need for faster ranking in tsearch2, since currently we should
consult heap to get positional information, which slowdowns search.
We didn't investigate the possibility to keep additional information with
index, but keep in mind, that everything should works without index.

Regards,
Oleg
_
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Guillaume Smet

On 2/22/07, Teodor Sigaev <[EMAIL PROTECTED]> wrote:

How long is average length of strings in table?


test=# SELECT MIN(length(word)), MAX(length(word)), AVG(length(word))
FROM lieu_mots_gin;
min | max |avg
-+-+
  1 |  38 | 7.4615463141373282
(1 row)

I don't see how to have a more precise similarity without having the
number of entries registered by the indexed value somewhere.

I think it can be interesting for other flavours of GIN usage. Is
there a way to add the number of entries of the considered indexed
item to the consistent prototype without adding too much overhead and
complexity?

--
Guillaume

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Teodor Sigaev

I didn't see any improvement in terms of size of the index (14 MB for
642 738 rows in the index in both cases) or speed.
Our dictionary table contains 78367 words and its size is 3 MB.

Did I miss something?
Comparing integers is cheaper than strings. Although it hasn't significant 
matter for index scan.



The attached patch adds a RECHECK too. It seems to work correctly but
the RECHECK COND costs a lot of time :/.


:(

How long is average length of strings in table?
--
Teodor Sigaev   E-mail: [EMAIL PROTECTED]
   WWW: http://www.sigaev.ru/

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Guillaume Smet

On 2/22/07, Teodor Sigaev <[EMAIL PROTECTED]> wrote:

>  From a previous discussion with Teodor, it would be better to store an
> int in the index instead of a text (it takes less space and is
> faster). I couldn't find any example so if anyone has an advice to fix
> that, it's welcome (mostly how to pack the trigram into an int instead
> of a text).

Something like that: [snip]


I worked on that this morning before I got your email. You'll find
attached a second version of the patch using int4 to store the
trigrams (it's not exactly what you gave me but it should work I
think).

I didn't see any improvement in terms of size of the index (14 MB for
642 738 rows in the index in both cases) or speed.
Our dictionary table contains 78367 words and its size is 3 MB.

Did I miss something?

If there's no benefit to use an int4, I propose we keep the text
version because it will be better if we add UTF-8 support someday.


our query. So, our consistent function should say FALSE when indexed value is
not similar to query exactly and TRUE in opposite case. Let lquery is a length
of query and ncommon is a number of common trigrams (look at cnt_sml()
function), and consistent function should be:


Yes, that's what I did in my patch if I understand you correctly but
it's not very selective IMHO.


Now consistent function doesn't guarantee exact result, so we should mark '%'
operator in CREATE OPERATOR CLASS with RECHECK option.


The attached patch adds a RECHECK too. It seems to work correctly but
the RECHECK COND costs a lot of time :/.

At the moment, I have the following results:
GIST:
---
test=# EXPLAIN ANALYZE SELECT word, similarity('aub', word) AS sml
FROM lieu_mots_gist WHERE word % 'aub' ORDER BY sml DESC;
  QUERY PLAN

Sort  (cost=204.40..204.59 rows=78 width=11) (actual
time=98.028..98.132 rows=50 loops=1)
  Sort Key: similarity('aub'::text, word)
  ->  Bitmap Heap Scan on lieu_mots_gist  (cost=4.88..201.95 rows=78
width=11) (actual time=97.575..97.861 rows=50 loops=1)
Recheck Cond: (word % 'aub'::text)
->  Bitmap Index Scan on idx_word_gist  (cost=0.00..4.86
rows=78 width=0) (actual time=97.539..97.539 rows=50 loops=1)
  Index Cond: (word % 'aub'::text)
Total runtime: 98.303 ms
(7 rows)

test=# EXPLAIN ANALYZE SELECT word, similarity('auberge', word) AS sml
FROM lieu_mots_gist WHERE word % 'auberge' ORDER BY sml DESC;
   QUERY PLAN
--
Sort  (cost=204.40..204.59 rows=78 width=11) (actual
time=135.128..135.196 rows=41 loops=1)
  Sort Key: similarity('auberge'::text, word)
  ->  Bitmap Heap Scan on lieu_mots_gist  (cost=4.88..201.95 rows=78
width=11) (actual time=134.829..135.016 rows=41 loops=1)
Recheck Cond: (word % 'auberge'::text)
->  Bitmap Index Scan on idx_word_gist  (cost=0.00..4.86
rows=78 width=0) (actual time=134.797..134.797 rows=41 loops=1)
  Index Cond: (word % 'auberge'::text)
Total runtime: 135.335 ms
(7 rows)

With GIN:


test=# EXPLAIN ANALYZE SELECT word, similarity('aub', word) AS sml
FROM lieu_mots_gin WHERE word % 'aub' ORDER BY sml DESC;
  QUERY PLAN
-
Sort  (cost=208.45..208.64 rows=78 width=11) (actual
time=60.409..60.513 rows=50 loops=1)
  Sort Key: similarity('aub'::text, word)
  ->  Bitmap Heap Scan on lieu_mots_gin  (cost=8.93..205.99 rows=78
width=11) (actual time=10.279..60.228 rows=50 loops=1)
Filter: (word % 'aub'::text)
->  Bitmap Index Scan on idx_word_gin  (cost=0.00..8.91
rows=78 width=0) (actual time=10.069..10.069 rows=6676 loops=1)
  Index Cond: (word % 'aub'::text)
Total runtime: 60.688 ms
(7 rows)

test=# EXPLAIN ANALYZE SELECT word, similarity('auberge', word) AS sml
FROM lieu_mots_gin WHERE word % 'auberge' ORDER BY sml DESC;
  QUERY PLAN

Sort  (cost=208.45..208.64 rows=78 width=11) (actual
time=50.293..50.381 rows=41 loops=1)
  Sort Key: similarity('auberge'::text, word)
  ->  Bitmap Heap Scan on lieu_mots_gin  (cost=8.93..205.99 rows=78
width=11) (actual time=21.006..50.122 rows=41 loops=1)
Filter: (word % 'auberge'::text)
->  Bitmap Index Scan on idx_word_gin  (cost=0.00..8.91
rows=78 width=0) (actual time=20.839..20.839 rows=928 loops=1)
  Index Cond: (word % 'auberge'::text)
Total runtime: 50.534 ms
(7 rows)


Re: [PATCHES] First implementation of GIN for pg_trgm

2007-02-22 Thread Teodor Sigaev

 From a previous discussion with Teodor, it would be better to store an
int in the index instead of a text (it takes less space and is
faster). I couldn't find any example so if anyone has an advice to fix
that, it's welcome (mostly how to pack the trigram into an int instead
of a text).


Something like that:
trg = generate_trgm(VARDATA(text), VARSIZE(text) - VARHDRSZ);
nentries = ARRNELEM(trg);
if ( nentries > 0 )
{
*entries = palloc(sizeof(Datum)*nentries);
for(i=0;i>= 8;
entries[i] = Int32GetDatum(tmp);
}
}
Do not forget to change CREATE OPERATOR CLASS accordingly.



The last problem is that similarity calculated in the GIN index is
higher than the one with GIST so I have to set the trgm_limit quite
high to have decent results (a limit of 0.8 instead of 0.3 seems to be
quite good).
AFAICS, it comes from the fact that I couldn't find any way to get the
length of the indexed trigram which is taken into account with GIST so
we're not exactly filtering the results in the same way.
Does anyone have an idea on how to fix this point?


For calculating similarity, you should have three value: length of first word 
(let it be a indexed text) in trigrams, length of second word (query word) and
number of the same trigrams on both words. It's a pity, but during index scan we 
don't know length of indexed text. So, in index scan (consistent function) we 
could not compute exact value of similarity, but we can compute lower limit.
For example, if our query has 50 trigrams and only one of them is a common for 
indexed value and query we can conclude that indexed value can not be similar to 
our query. So, our consistent function should say FALSE when indexed value is 
not similar to query exactly and TRUE in opposite case. Let lquery is a length 
of query and ncommon is a number of common trigrams (look at cnt_sml() 
function), and consistent function should be:

#ifdef DIVUNION
/* original formula is: count/(lvalue+lquery-lcommon), so
   with any lvalue > 0 resulting similarity is smaller than
   computed below */
 return ( count/(lquery-lcommon) > limit ) ? TRUE : FALSE;
#else
/* original formula is: count/max(lvalue,lquery) - the same discourse */
return ( count/lquery > limit ) ? TRUE : FALSE;
#endif

Now consistent function doesn't guarantee exact result, so we should mark '%' 
operator in CREATE OPERATOR CLASS with RECHECK option.


--
Teodor Sigaev   E-mail: [EMAIL PROTECTED]
   WWW: http://www.sigaev.ru/

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] [previously on HACKERS] "Compacting" a relation

2007-02-22 Thread Simon Riggs
On Wed, 2007-02-21 at 21:28 -0300, Alvaro Herrera wrote:
> Bruce Momjian wrote:
> > Alvaro Herrera wrote:
> > > Bruce Momjian wrote:
> > > > 
> > > > I applied the optional VACUUM FULL version, but modified to code to say
> > > > 20% rather than a factor of 5, attached.
> > > 
> > > String construction does not work well with translations; please
> > > reformulate this.
> > > 
> > > > +errhint("Consider%sincreasing the 
> > > > configuration parameter \"max_fsm_pages\".",
> > > > +   /* Only suggest VACUUM 
> > > > FULL if 20% free */
> > > > +   
> > > > (vacrelstats->tot_free_pages > vacrelstats->rel_pages * 0.20
> > > > +   ? " using 
> > > > VACUUM FULL on this relation or ": " ";
> > 
> > OK, updated.
> 
> Thanks :-)

Alvaro: point noted for future. Bruce: many thanks.

-- 
  Simon Riggs 
  EnterpriseDB   http://www.enterprisedb.com



---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


[PATCHES] [test]

2007-02-22 Thread Gregory Stark

[testing to see if -patches allows me to post yet. I send a patch last night
but haven't seen it come through]

-- 
  Gregory Stark
  EnterpriseDB  http://www.enterprisedb.com

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly