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 ...
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| 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/ |
| |||
| 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 |
| |||
| Tom Lane wrote: 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... 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/ |
| |||
| 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) Â*Â* ->Â* 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) Â*Â* ->Â* 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/ |
| |||
| 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 |
| |||
| 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 )] |
| ||||
| 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 |