Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1Zt8yu-00036E-KZ for pgsql-performance@arkaria.postgresql.org; Mon, 02 Nov 2015 06:52:40 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1Zt8yu-00009W-2m for pgsql-performance@arkaria.postgresql.org; Mon, 02 Nov 2015 06:52:40 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1Zt8ys-00008j-QF for pgsql-performance@postgresql.org; Mon, 02 Nov 2015 06:52:39 +0000 Received: from mail-wm0-x233.google.com ([2a00:1450:400c:c09::233]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1Zt8yp-00017Z-Vk for pgsql-performance@postgresql.org; Mon, 02 Nov 2015 06:52:37 +0000 Received: by wmeg8 with SMTP id g8so50710125wme.0 for ; Sun, 01 Nov 2015 22:52:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=EsSzDGCbye5xB+nqedo4BtypGsxQk9i6padtjohGW38=; b=fRIhWsUYodI/6D+PmJtapvuZEpvsOxOsCWRefRvQgnI0vnHqVj9+71m4IHEpJSFHh2 NvkCtCll5pgO/Rd7Zo8EAczmSEfu5HBK6osxCqcW8tteArPZdtevHMfTpQlk5BisAnvs 3UrIDQAZ11pCzn94T+rdlZhhdVaYaYPWg1+DVoN8OtGwmtCItAvGFaWzplfB0hmWtPhU Los8lQiJtlIvCUUvVfL6Ms/cUD97oulVWpfKK3LMPuBI6ONUDAl22RJIwSu3y7K+yWjQ aaVnI+BS+h03Inc2aOOe1Ok4H0/F9qrzIQR4psyGE/NIiIldSLN8V6GRsnRa2PUv/Y4j 91mw== MIME-Version: 1.0 X-Received: by 10.28.55.144 with SMTP id e138mr10856690wma.69.1446447153360; Sun, 01 Nov 2015 22:52:33 -0800 (PST) Received: by 10.27.15.146 with HTTP; Sun, 1 Nov 2015 22:52:33 -0800 (PST) Date: Mon, 2 Nov 2015 09:52:33 +0300 Message-ID: Subject: GIN index always doing Re-check condition, postgres 9.1 From: Andrey Osenenko To: pgsql-performance@postgresql.org Content-Type: multipart/alternative; boundary=001a1143c552c3376605238938fc X-Pg-Spam-Score: -2.0 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org --001a1143c552c3376605238938fc Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I have a table with roughly 300 000 rows, each row containing two large strings - one is news article HTML, the other is news article plaintext. The table has a bigint primary key. A GIN index is used to do fulltext search on the plaintext part. All I want to retrieve when I do fulltext search is values of primary key column. With a popular word, the amount of results from fulltext search query can be pretty high - a query can return 23 000 rows and some can more, and will return more as the database continues to grow. The problem I have is that postgres always does Re-check condition step for my request. That query with 23k rows takes 20 seconds to execute, and EXPLAIN shows that almost all of that time is spent re-checking condition. The second time I run the same query, I get results immediately. What this means is that every time user does a search for some word no one searched before, he has to wait a very long time, which is unacceptable for us. Is this happening by design, or am I doing something wrong? The way I see it, since docs say GIN indexes are lossless, the database should be able to fetch just primary key values for matching rows for me. Here's schema, query, explain and database version: CREATE TABLE kard_md.fulldata ( id_iu bigint NOT NULL, url character varying NOT NULL, original text, edited text, plaintext text, date timestamp without time zone, CONSTRAINT fulldata_pkey PRIMARY KEY (id_iu) ); CREATE INDEX fulldata_plaintext_idx ON kard_md.fulldata USING gin (to_tsvector('russian'::regconfig, plaintext)); EXPLAIN (ANALYZE, BUFFERS) select id_iu from kard_md.fulldata where to_tsvector('russian',fulldata.plaintext) @@ plainto_tsquery('russian','=D0=BC=D0=BE=D1=81=D0=BA=D0=B2=D0=B0'); 1st run: Bitmap Heap Scan on fulldata (cost=3D266.79..39162.57 rows=3D23069 width= =3D8) (actual time=3D135.727..19499.667 rows=3D23132 loops=3D1) Recheck Cond: (to_tsvector('russian'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery) Buffers: shared hit=3D115 read=3D13000 -> Bitmap Index Scan on fulldata_plaintext_idx (cost=3D0.00..261.02 rows=3D23069 width=3D0) (actual time=3D104.834..104.834 rows=3D23132 loops= =3D1) Index Cond: (to_tsvector('russian'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery) Buffers: shared hit=3D3 read=3D21 Total runtime: 19512.479 ms 2nd run: Bitmap Heap Scan on fulldata (cost=3D266.79..39162.57 rows=3D23069 width= =3D8) (actual time=3D25.423..48.649 rows=3D23132 loops=3D1) Recheck Cond: (to_tsvector('russian'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery) Buffers: shared hit=3D13115 -> Bitmap Index Scan on fulldata_plaintext_idx (cost=3D0.00..261.02 rows=3D23069 width=3D0) (actual time=3D18.057..18.057 rows=3D23132 loops=3D= 1) Index Cond: (to_tsvector('russian'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery) Buffers: shared hit=3D24 Total runtime: 49.612 ms select version() 'PostgreSQL 9.1.15, compiled by Visual C++ build 1500, 64-bit' --001a1143c552c3376605238938fc Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
I have a table with roughly 300 0= 00 rows, each row containing two large strings - one is news article HTML, = the other is news article plaintext. The table has a bigint primary key.
A GIN index is used to do fulltext search on the plaintext part.= All I want to retrieve when I do fulltext search is values of primary key = column.

With a popular word, the amount of results from fullte= xt search query can be pretty high - a query can return 23 000 rows and som= e can more, and will return more as the database continues to grow.

= The problem I have is that postgres always does Re-check condition step for= my request. That query with 23k rows takes 20 seconds to execute, and EXPL= AIN shows that almost all of that time is spent
re-checking condit= ion. The second time I run the same query, I get results immediately.
What this means is that every time user does a search for some wor= d no one searched before, he has to wait a very long time, which is unaccep= table for us.

Is this happening by design, or am I = doing something wrong? The way I see it, since docs say GIN indexes are los= sless, the database should be able to fetch just primary key values for mat= ching rows for me.

Here's schema, query, explain and datab= ase version:

CREATE TABLE kard_md.fulldata
(
=C2=A0 id_iu= bigint NOT NULL,
=C2=A0 url character varying NOT NULL,
=C2=A0 origi= nal text,
=C2=A0 edited text,
=C2=A0 plaintext text,
=C2=A0 date t= imestamp without time zone,
=C2=A0 CONSTRAINT fulldata_pkey PRIMARY KEY = (id_iu)
);

CREATE INDEX fulldata_plaintext_idx
=C2=A0 ON kard_= md.fulldata
=C2=A0 USING gin
=C2=A0 (to_tsvector('russian'::r= egconfig, plaintext));


EXPLAIN (ANALYZE, BUFFERS) select id_iu f= rom kard_md.fulldata where to_tsvector('russian',fulldata.plaintext= ) @@ plainto_tsquery('russian','=D0=BC=D0=BE=D1=81=D0=BA=D0=B2= =D0=B0');

1st run:
Bitmap Heap Scan on fulldata=C2=A0 (cost= =3D266.79..39162.57 rows=3D23069 width=3D8) (actual time=3D135.727..19499.6= 67 rows=3D23132 loops=3D1)
=C2=A0 Recheck Cond: (to_tsvector('russia= n'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0=BA=D0= =B2'''::tsquery)
=C2=A0 Buffers: shared hit=3D115 read=3D130= 00
=C2=A0 ->=C2=A0 Bitmap Index Scan on fulldata_plaintext_idx=C2=A0 = (cost=3D0.00..261.02 rows=3D23069 width=3D0) (actual time=3D104.834..104.83= 4 rows=3D23132 loops=3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Ind= ex Cond: (to_tsvector('russian'::regconfig, plaintext) @@ ''= ;'=D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery)
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffers: shared hit=3D3 read=3D21
Tota= l runtime: 19512.479 ms

2nd run:
Bitmap Heap Scan on fulldata=C2= =A0 (cost=3D266.79..39162.57 rows=3D23069 width=3D8) (actual time=3D25.423.= .48.649 rows=3D23132 loops=3D1)
=C2=A0 Recheck Cond: (to_tsvector('r= ussian'::regconfig, plaintext) @@ '''=D0=BC=D0=BE=D1=81=D0= =BA=D0=B2'''::tsquery)
=C2=A0 Buffers: shared hit=3D13115=C2=A0 ->=C2=A0 Bitmap Index Scan on fulldata_plaintext_idx=C2=A0 (cost= =3D0.00..261.02 rows=3D23069 width=3D0) (actual time=3D18.057..18.057 rows= =3D23132 loops=3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Index Con= d: (to_tsvector('russian'::regconfig, plaintext) @@ '''= =D0=BC=D0=BE=D1=81=D0=BA=D0=B2'''::tsquery)
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffers: shared hit=3D24
Total runtime: 49.6= 12 ms

select version()
'PostgreSQL 9.1.15, compiled by Visual= C++ build 1500, 64-bit'


--001a1143c552c3376605238938fc--