未使用Postgresql索引

未使用Postgresql索引,postgresql,Postgresql,我试图理解为什么此查询不使用索引: SELECT te.idturno FROM turno t JOIN turnoestado te ON t.idturno = te.idturno ORDER BY te.idturno, te.idturnoestado Limit 100 转盘的行数约为100万,转盘的行数约为1000万 以下是索引定义: CREATE INDEX idx_turnoestado_idturno ON turnoestado USING btree (id

我试图理解为什么此查询不使用索引:

SELECT 
  te.idturno
FROM turno t
JOIN turnoestado te ON t.idturno = te.idturno
ORDER BY te.idturno, te.idturnoestado
Limit 100
转盘的行数约为100万,转盘的行数约为1000万

以下是索引定义:

CREATE INDEX idx_turnoestado_idturno
  ON turnoestado USING btree (idturno);

CREATE INDEX idx_turnoestado_idturnoestado
  ON turnoestado USING btree (idturnoestado);
如您所见,Order By子句中使用的键有两个索引,但根据explain ANALYSE返回的查询计划,没有一个索引被使用:

Limit  (cost=988700.56..988700.81 rows=100 width=8) (actual time=7332.740..7332.754 rows=100 loops=1)
  ->  Sort  (cost=988700.56..1014125.36 rows=10169918 width=8) (actual time=7332.737..7332.746 rows=100 loops=1)
        Sort Key: te.idturno, te.idturnoestado
        Sort Method: top-N heapsort  Memory: 29kB
        ->  Hash Join  (cost=160603.86..600013.61 rows=10169918 width=8) (actual time=505.221..6279.233 rows=10169918 loops=1)
              Hash Cond: (te.idturno = t.idturno)
              ->  Seq Scan on turnoestado te  (cost=0.00..178003.18 rows=10169918 width=8) (actual time=0.011..1249.563 rows=10169918 loops=1)
              ->  Hash  (cost=143894.94..143894.94 rows=1018394 width=4) (actual time=504.731..504.731 rows=1018394 loops=1)
                    Buckets: 4096  Batches: 64  Memory Usage: 571kB
                    ->  Seq Scan on turno t  (cost=0.00..143894.94 rows=1018394 width=4) (actual time=0.033..342.071 rows=1018394 loops=1)
Total runtime: 7332.824 ms
如果我在orderby中只使用一个键,结果是瞬时的,如果我创建一个多列索引,情况也是如此。为什么计划员不使用已创建的索引


注意:我正在使用“PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu,由gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2编译,64位”

您确定“explain”输出是您发布的SELECT语句的输出吗?我觉得这很难相信。@MikeSherrill'CatRecall',我忘了包括限额。现在我替换了原来的查询和计划,请看一看。它看起来像是使用btree(iturno,idturnoestado)在turnoestado上的复合索引
可能会有帮助。(但是由于连接产生整个10M行,索引最多可以避免排序步骤(~1秒))好的@joop,我包括了一个复合索引,它确实非常快。现在,更进一步,我添加了一个where子句作为“where te.estado in('E','W','S'),它再次删除了索引用法。这是为什么?我发现了一些有趣的事情,如果我用一个包含值“E”、“W”和“s”的表的内部联接替换where,那么查询运行得非常快。