Sql 为什么不是';用于此查询的t索引?

Sql 为什么不是';用于此查询的t索引?,sql,postgresql,Sql,Postgresql,我有一个表,有300K行,在“操作符”字段上有b树索引。 当我运行这个查询时,它没有使用索引。 “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 fli

我有一个表,有300K行,在“操作符”字段上有b树索引。 当我运行这个查询时,它没有使用索引。 “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)"

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

你在dict.vw\u dict\u操作符上有什么索引

EXISTS是连接的一种形式(我知道这很简单),索引可能会被忽略,因为没有方便的连接对象。所以它会扫描

编辑:


加入计划也没有使用关于TIU航班可用性的索引。。。但是你说上面有索引?

为什么不使用连接?你分析了吗?统计数字呢?检查此表的pg_统计以获取更多信息。pg_类中的reltuple和relpages对于表及其索引也很有趣


编辑: 联接需要228639行。顺序扫描需要303733行,只是额外的一小部分。当这些100k记录到处都是时,数据库无论如何都必须扫描这些页面。顺序扫描比索引扫描快,顺序扫描是(快速)顺序读取,索引扫描是两次(!)慢速随机读取:索引中的信息和表中的数据

如果您认为该计划是错误的,请分析该表并向我们显示来自pgu stats和pgu类的关于表和索引的信息

ANALYZE;

SELECT relpage, reltuples WHERE relname = 'table_or_index_name';

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

创建表dict.dict_运算符(id整数不为空,约束pk_dict_运算符主键(id))@noxvile:和ti_flight_可用性?使用btree(运算符)在ti.ti_flight_可用性上创建索引ix_ti_flight_可用性_运算符;我不知道如何使用索引,但依赖子查询通常不是一个好方法。@R.Bemrose您能在没有子查询的情况下为这个任务编写实现吗?对不起,JOIN也不使用索引。执行分析需要很长时间。reltuples:303733 relpages:4717不幸的是,我不知道我可以从pgu类中获取哪些有用的信息,pgu stats查看我的编辑,您必须进行分析。你可以在这些桌子上做,但你必须做。您有什么版本的PostgreSQL?版本8.3 reltuples:303733 relpages:4717运算符上的索引没有多大帮助,303733记录上只有80个不同的值。这80个值将到处都是,数据库必须读取整个表,进行顺序扫描。使用EXISTS的原始查询是一个更好的查询。