开发者

Why isn't index used for this query?

I have a table with 300K rows and b-tree index on "operator" field. While I'm runnig this query it isn't using an index. "operator" has the same data-type as dict.vw_dict_operator.id.

EXPLAIN SELECT  
    id,
    name
FROM
    dict.vw_dict_operator self 
WHERE

            EXISTS (
                SELECT 42 FROM ti.ti_flight_availability flight_avail
                WHERE flight_avail.operator = self.id
            )   
ORDER BY
    self.name 

"Sort  (cost=3349.66..3351.02 rows=545 width=18)"
"  Sort Key: dict_operator.name"
"  ->  Seq Scan on dict_operator  (cost=0.00..3324.89 rows=545 width=18)"
"        Filter: ((NOT trash)开发者_运维知识库 AND (subplan))"
"        SubPlan"
"          ->  Seq Scan on ti_flight_availability flight_avail  (cost=0.00..8513.66 rows=3750 width=0)"
"                Filter: (operator = $0)"

UPD: thanks @gbn. index isnot used when joining tables as well

EXPLAIN SELECT self.id, self.name 
FROM dict.vw_dict_operator self JOIN ti.ti_flight_availability flight_avail
ON flight_avail.operator = self.id

"Nested Loop  (cost=0.00..92988.47 rows=228639 width=18)"
"  ->  Seq Scan on ti_flight_availability flight_avail  (cost=0.00..7754.33 rows=303733 width=4)"
"  ->  Index Scan using pk_dict_operator on dict_operator  (cost=0.00..0.27 rows=1 width=18)"
"        Index Cond: (dict_operator.id = flight_avail.operator)"
"        Filter: (NOT dict_operator.trash)"


Why don't you use a JOIN? And did you ANALYZE? What about the statistics? Check pg_stats for this table to get some more information. reltuples and relpages in pg_class are also interesting for the table and it's indexes.


Edit: The JOIN expects 228639 rows. The sequential scan expects 303733 rows, only a fraction extra. When these 100k records are all over the place, the database has to scan the relpages anyway. A sequential scan will be faster than an index scan, a sequential scan a (fast) sequentail read, an index scan will be two (!) slow random reads: the information from the index and the data from the table.

If you think the plan is wrong, ANALYZE the table and show us information from pg_stats and pg_class about the tables and indexes.

ANALYZE;

SELECT relpage, reltuples WHERE relname = 'table_or_index_name';

SELECT * FROM pg_stats WHERE tablename = 'name of your table';


Would it use the index if you did a join instead?


What index you have have on dict.vw_dict_operator?

EXISTS is a form of JOIN (simplistic, I know) and it's possible the index is ignored because there is no convenient one to JOIN to. So it scans instead.

Edit:

the JOIN plan is not using an index on ti_flight_availability either... but you state you have an index on it?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜