Unix Technical Forum

Difference between "foo is false" and "foo=false"? Partial indexon boolean.

This is a discussion on Difference between "foo is false" and "foo=false"? Partial indexon boolean. within the pgsql Sql forums, part of the PostgreSQL category; --> Expecting to save 4 seconds per query, I built a partial index on a table, and was surprised that ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > pgsql Sql

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-19-2008, 05:52 PM
Bryce Nesbitt
 
Posts: n/a
Default Difference between "foo is false" and "foo=false"? Partial indexon boolean.

Expecting to save 4 seconds per query, I built a partial index on a table, and was surprised that it did not work.Â* Could someone explain the difference between "foo=false" and "foo is false", for a boolean type column?

stage=# create index eg_ve_reconciled_partial on eg_vehicle_event (reconciled) where reconciled=false;
stage=# select pg_total_relation_size('eg_ve_reconciled_partial') ;
Â*pg_total_relation_size
------------------------
Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* 8192


stage=# explain select count(*) from EG_VEHICLE_EVENT where reconciled is false;
--------------------------------------------------------------------------
Â*AggregateÂ* (cost=33169.57..33169.58 rows=1 width=0)
Â*Â* ->Â* Seq Scan on eg_vehicle_eventÂ* (cost=0.00..33169.57 rows=1 width=0)
Â*Â*Â*Â*Â*Â*Â*Â* Filter: (reconciled IS FALSE)



stage=# explain select count(*) from EG_VEHICLE_EVENT where reconciled=false;
-------------------------------------------------------------------------------------------------------
Â*AggregateÂ* (cost=1.02..1.03 rows=1 width=0)
Â*Â* ->Â* Index Scan using eg_ve_reconciled_partial on eg_vehicle_eventÂ* (cost=0.00..1.01 rows=1 width=0)
Â*Â*Â*Â*Â*Â*Â*Â* Index Cond: (reconciled = false)


The problem is that my test query above is fast, but the real query from Hibernate is still dog slow.Â* Here's the pg_log entry:

LOG:Â* duration: 4260.575 msÂ* statement: EXECUTE C_50292Â* [PREPARE:Â* select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1 ) and (vehicleeve0_.RECONCILED=$2 )]


I tried building two indexes, one for "is false" one for "=false", but the Hibernate query is still slow.Â* Yet the hand-run versionÂ* uses the index easily:

stage=# explain analyze select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=2 )and(vehicleeve0_.RECONCILED=false);
Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â* QUERY PLANÂ*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* Â*Â*Â*Â*Â*
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Â*AggregateÂ* (cost=81.75..81.76 rows=1 width=4) (actual time=56.153..56.154 rows=1 loops=1)
Â*Â* ->Â* Index Scan using eg_ve_reconciled_partial on eg_vehicle_event vehicleeve0_Â* (cost=0.00..60.05 rows=8679 width=4) (actual time=0.126..44.548 rows=10345 loops=1)
Â*Â*Â*Â*Â*Â*Â*Â* Index Cond: (reconciled = false)
Â*Â*Â*Â*Â*Â*Â*Â* Filter: (cso_id = 2)
Â*Total runtime: 64.825 ms
(5 rows)




-- ---- Visit http://www.obviously.com/

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-19-2008, 05:52 PM
Tom Lane
 
Posts: n/a
Default Re: Difference between "foo is false" and "foo=false"? Partial index on boolean.

Bryce Nesbitt <bryce1@obviously.com> writes:
> Could someone explain
> the difference between "foo=false" and "foo is false", for a boolean
> type column?


They give different results for NULL --- specifically, NULL for the
former and FALSE for the latter. Don't blame me, it's in the spec...

regards, tom lane

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-19-2008, 05:52 PM
Bryce Nesbitt
 
Posts: n/a
Default Re: Difference between "foo is false" and "foo=false"? Partialindex on boolean.

Tom Lane wrote:

Bryce Nesbitt &lt;bryce1@obviously.com&gt; writes:



Could someone explain the difference between "foo=false" and "foo is false", for a boolean type column?



They give different results for NULL --- specifically, NULL for the former and FALSE for the latter. Don't blame me, it's in the spec...

Thanks, and Got It.Â* This particular column is:
Â*Â*Â* reconciledÂ*Â*Â*Â*Â*Â* | booleanÂ*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â*Â* | not null
On PostgreSQL 8.1.9.


So given all that, why would the Hibernate query fail to use the partial index?Â*Â* I eventually created three indexes, and only the hideously large full index increases performance:

Indexes:
Â*Â*Â* "eg_vehicle_event_pkey" PRIMARY KEY, btree (vehicle_event_id)
Â*Â*Â* "no_duplicate_events" UNIQUE, btree (cso_id, event_type, "timestamp", fob_number, hardware_number)
Â*Â*Â* "eg_ve_reconciled_full" btree (reconciled)
Â*Â*Â* "eg_ve_reconciled_partial" btree (reconciled) WHERE reconciled = false
Â*Â*Â* "eg_ve_reconciled_partial_is" btree (reconciled) WHERE reconciled IS FALSE
Foreign-key constraints:
Â*Â*Â* "fk_event_admin" FOREIGN KEY (admin_id) REFERENCES eg_admin(admin_id)
Â*Â*Â* "fkd28396aacabde72e" FOREIGN KEY (vehicle_id) REFERENCES eg_vehicle(vehicle_id)
Â*Â*Â* "fkd28396aaf61930e0" FOREIGN KEY (member_id) REFERENCES eg_member(member_id)


Only the full index prevents a "false" scan from taking 4 seconds:

LOG:Â* duration: 4260.575 msÂ* statement: EXECUTE C_50292Â* [PREPARE:Â* select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1 ) and (vehicleeve0_.RECONCILED=$2 )]




-- ---- Visit http://www.obviously.com/

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-19-2008, 05:52 PM
Bryce Nesbitt
 
Posts: n/a
Default Partial index on boolean - Sometimes fails to index scan

This is a reformulation of an earlier question.Â* I've got a confusing case of a partial index not working.Â* The column in question is a not-null boolean, which is false only for the most recent entries into the table.

# explain analyze select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=2 )and(vehicleeve0_.RECONCILED=false);
QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------
Â*AggregateÂ* (cost=49184.62..49184.64 rows=1 width=4) (actual time=2017.793..2017.794 rows=1 loops=1)
Â*Â* -&gt;Â* Seq Scan on eg_vehicle_event vehicleeve0_Â* (cost=0.00..49162.93 rows=8679 width=4) (actual time=1202.175..2006.169 rows=10342 loops=1)
Â*Â*Â*Â*Â*Â*Â*Â* Filter: ((cso_id = 2) AND (NOT reconciled))
Total runtime: 2018.052 ms

stage=# create index eg_ve_reconciled_partial on eg_vehicle_event (reconciled) where reconciled=false;

stage=# select pg_total_relation_size('eg_ve_reconciled_partial') ;
204800

# explain analyze select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=2 )and(vehicleeve0_.RECONCILED=false);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Â*AggregateÂ* (cost=81.75..81.76 rows=1 width=4) (actual time=56.218..56.219 rows=1 loops=1)
Â*Â* -&gt;Â* Index Scan using eg_ve_reconciled_partial on eg_vehicle_event vehicleeve0_Â* (cost=0.00..60.05 rows=8679 width=4) (actual time=0.118..44.647 rows=10342 loops=1)
Â*Â*Â*Â*Â*Â*Â*Â* Index Cond: (reconciled = false)
Â*Â*Â*Â*Â*Â*Â*Â* Filter: (cso_id = 2)
Â*Total runtime: 56.312 ms


Which is all good.Â* But the Hibernate version of query still takes several seconds, and still appears in my pg_log slow query log:

LOG:Â* duration: 2248.662 msÂ* statement: EXECUTE C_51443Â* [PREPARE:Â* select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1 )and(vehicleeve0_.RECONCILED=$2 )]

A full index on 'reconciled' speeds up the query.Â* But why should the partial index not also do it?Â* Any idea why apparently identical queries give different partial index scan results?Â* PostgreSQL 8.1.9.



-- ---- Visit http://www.obviously.com/

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-19-2008, 05:52 PM
Richard Huxton
 
Posts: n/a
Default Re: Difference between "foo is false" and "foo=false"? Partialindex on boolean.

Bryce Nesbitt wrote:
> Tom Lane wrote:
>> Bryce Nesbitt <bryce1@obviously.com> writes:
>>
>> They give different results for NULL --- specifically, NULL for the
>> former and FALSE for the latter. Don't blame me, it's in the spec...

> Thanks, and Got It. This particular column is:
> reconciled | boolean | not null
> On PostgreSQL 8.1.9.


> So given all that, why would the Hibernate query fail to use the partial
> index? I eventually created three indexes, and only the hideously large full
> index increases performance:


> Only the full index prevents a "false" scan from taking 4 seconds:
>
> LOG: duration: 4260.575 ms statement: EXECUTE C_50292 [PREPARE: select
> count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_
> where (vehicleeve0_.CSO_ID=$1 ) and (vehicleeve0_.*RECONCILED=$2* )]


It's a prepared query-plan, which means it can't plan to use the index
because the next EXECUTE might have reconciled=true.

--
Richard Huxton
Archonet Ltd

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 04-19-2008, 05:52 PM
Bryce Nesbitt
 
Posts: n/a
Default Re: Partial index on boolean - Sometimes fails to index scan

Richard Huxton provided the answer: It's a prepared query-plan, which means it can't plan to use the index because the next EXECUTE might have reconciled=true.

Bryce Nesbitt wrote: ....Which is all good.Â* But the Hibernate version of query still takes several seconds, and still appears in my pg_log slow query log:

LOG:Â* duration: 2248.662 msÂ* statement: EXECUTE C_51443Â* [PREPARE:Â* select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1 )and(vehicleeve0_.RECONCILED=$2 )]
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 04-19-2008, 05:52 PM
PostgreSQL Admin
 
Posts: n/a
Default Trigger to change different row in same table

I want to write a trigger that updates a different row on the same
table. It's pretty basic: before the any row in his table updated I
want to set a only row that has the value true to false. I keep getting
this error:

SQL statement "update theirry.articles set master_featured = false where
master_featured = true"
PL/pgSQL function "master_featured_maintenance" line 4 at SQL statement

My basic trigger:

CREATE OR REPLACE FUNCTION theirry.master_featured_maintenance()
RETURNS TRIGGER AS
$master_featured_maintenance$
DECLARE
master_feature boolean;
BEGIN
update theirry.articles
set master_featured = false
where master_featured = true;
END;
$master_featured_maintenance$
LANGUAGE plpgsql;

CREATE TRIGGER master_featured_maintenance
BEFORE INSERT OR UPDATE ON theirry.articles
FOR EACH ROW EXECUTE PROCEDURE theirry.master_featured_maintenance();


Thanks in advance,
J

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 04:41 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
www.UnixAdminTalk.com