Why is the following query getting wrong estimation of rows? I am using Postgresql 9.2.1 with default_statistics_target = 100. I execute vacuum analyze each night.
explain analyze SELECT entity.id AS "Leads_id", entity.type AS "Leads_type" , leads.firstname AS "Leads_firstname", leads.lastname AS "Leads_lastname" FROM leads INNER JOIN entity ON leads.leadid=entity.id LEFT JOIN groups ON groups.groupid = entity.smownerid LEFT join users ON entity.smownerid= users.id WHERE entity.type='Leads' AND entity.deleted=0 AND leads.converted=0 Hash Join (cost=14067.90..28066.53 rows=90379 width=26) (actual time=536.009..1772.910 rows=337139 loops=1) Hash Cond: (leads.leadid = entity.id) -> Seq Scan on leads (cost=0.00..7764.83 rows=533002 width=18) (actual time=0.008..429.576 rows=532960 loops=1) Filter: (converted = 0) -> Hash (cost=9406.25..9406.25 rows=372932 width=16) (actual time=535.800..535.800 rows=342369 loops=1) Buckets: 65536 Batches: 1 Memory Usage: 16049kB -> Index Scan using entity_type_idx on entity (cost=0.00..9406.25 rows=372932 width=16) (actual time=0.030..305.250 rows=342369 loops=1) Index Cond: ((type)::text = 'Leads'::text) \d leads Table "public.leads" Column | Type | Modifiers ------------------+------------------------+--------------------------------------- leadid | integer | not null email | character varying(100) | interest | character varying(50) | firstname | character varying(100) | salutation | character varying(200) | lastname | character varying(100) | not null company | character varying(200) | not null annualrevenue | integer | default 0 industry | character varying(200) | campaign | character varying(30) | rating | character varying(200) | leadstatus | character varying(50) | leadsource | character varying(200) | converted | integer | default 0 designation | character varying(200) | default 'SalesMan'::character varying licencekeystatus | character varying(50) | space | character varying(250) | comments | text | priority | character varying(50) | demorequest | character varying(50) | partnercontact | character varying(50) | productversion | character varying(20) | product | character varying(50) | maildate | date | nextstepdate | date | fundingsituation | character varying(50) | purpose | character varying(50) | evaluationstatus | character varying(50) | transferdate | date | revenuetype | character varying(50) | noofemployees | integer | yahooid | character varying(100) | assignleadchk | integer | default 0 department | character varying(200) | emailoptout | character varying(3) | default 0 siccode | character varying(50) | Indexes: "leads_pkey" PRIMARY KEY, btree (leadid) "ftx_en_leads_company" gin (to_tsvector('v_en'::regconfig, for_fts(company::text))) "ftx_en_leads_email" gin (to_tsvector('v_en'::regconfig, for_fts(email::text))) "ftx_en_leads_emailoptout" gin (to_tsvector('v_en'::regconfig, for_fts(emailoptout::text))) "ftx_en_leads_firstname" gin (to_tsvector('v_en'::regconfig, for_fts(firstname::text))) "ftx_en_leads_lastname" gin (to_tsvector('v_en'::regconfig, for_fts(lastname::text))) "ftx_en_leads_yahooid" gin (to_tsvector('v_en'::regconfig, for_fts(yahooid::text))) "leads_converted_idx" btree (converted) "leads_leadsource_idx" btree (leadsource) "leads_leadstatus_idx" btree (leadstatus) \d entity Table "public.entity" Column | Type | Modifiers --------------------+-----------------------------+------------------------------ id | integer | not null smcreatorid | integer | not null default 0 smownerid | integer | not null default 0 modifiedby | integer | not null default 0 setype | character varying(30) | not null description | text | createdtime | timestamp without time zone | not null modifiedtime | timestamp without time zone | not null viewedtime | timestamp without time zone | status | character varying(50) | version | integer | not null default 0 presence | integer | default 1 deleted | integer | not null default 0 owner_type | character(1) | not null default 'U'::bpchar last_activity_date | timestamp without time zone | Indexes: "entity_pkey" PRIMARY KEY, btree (id) "entity_createdtime_idx" btree (createdtime) "entity_modifiedby_idx" btree (modifiedby) "entity_modifiedtime_idx" btree (modifiedtime) "entity_setype_idx" btree (setype) WHERE deleted = 0 "entity_smcreatorid_idx" btree (smcreatorid) "entity_smownerid_idx" btree (smownerid) "ftx_en_entity_description" gin (to_tsvector('v_en'::regconfig, for_fts(description))) "entity_deleted_idx" btree (deleted) Referenced by: TABLE "service" CONSTRAINT "fk_1_service" FOREIGN KEY (serviceid) REFERENCES entity(id) ON DELETE CASCADE TABLE "servicecontracts" CONSTRAINT "fk_1_servicecontracts" FOREIGN KEY (servicecontractsid) REFERENCES entity(id) ON DELETE CASCADE TABLE "_emails" CONSTRAINT "fk__emails_id" FOREIGN KEY (id) REFERENCES entity(id) ON DELETE CASCADE Please advice. Thanks.