为什么索引不用于此查询?

时间:2010-08-31 18:58:23

标签: sql postgresql

我在“operator”字段上有一个300K行和b-tree索引的表。 虽然我运行此查询但它没有使用索引。 “operator”与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:谢谢@gbn。连接表时也不使用索引

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)"

3 个答案:

答案 0 :(得分:2)

为什么不使用JOIN?你有分析吗?统计数据怎么样?检查此表的pg_stats以获取更多信息。 pg_class中的reltuples和relpup对于表及其索引也很有趣。


编辑: JOIN期望228639行。顺序扫描需要303733行,只有一小部分。当这些100k记录遍布整个地方时,数据库无论如何都必须扫描重新分页。顺序扫描将比索引扫描更快,顺序扫描(快速)序列读取,索引扫描将是两个(!)慢随机读取:来自索引的信息来自索引的信息桌子。

如果您认为该计划有误,请对该表进行分析,并向我们展示pg_stats和pg_class中有关表和索引的信息。

ANALYZE;

SELECT relpage, reltuples WHERE relname = 'table_or_index_name';

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

答案 1 :(得分:0)

如果您改为加入,它会使用索引吗?

答案 2 :(得分:0)

你对dict.vw_dict_operator有什么索引?

EXISTS是JOIN的一种形式(简单,我知道),并且可能会忽略索引,因为没有方便的JOIN。所以它会扫描。

编辑:

JOIN计划也没有在ti_flight_availability上使用索引......但是你声明你有一个索引吗?