Sql 索引以提高排序性能?

Sql 索引以提高排序性能?,sql,postgresql,Sql,Postgresql,我有一个相当复杂的查询,其中包括一个orderby和一个LIMIT子句。当排序依据使用主键时,查询所需时间少于5毫秒。但是,如果我更改查询,使ORDER BY由不同的列(类型为FLOAT)完成,则响应时间会膨胀到50秒以上(高出四个数量级!) 现在,我假设问题在于,按主键排序的查询执行索引扫描,而按float列排序的查询执行顺序扫描,并且需要在最后进行排序 我认为只要在float列上添加一个索引就足以让Postgresql以更智能的方式规划这个查询。显然我错了。我可能错过了什么 编辑:在发布问题

我有一个相当复杂的查询,其中包括一个
orderby
和一个
LIMIT
子句。当排序依据使用主键时,查询所需时间少于5毫秒。但是,如果我更改查询,使
ORDER BY
由不同的列(类型为
FLOAT
)完成,则响应时间会膨胀到50秒以上(高出四个数量级!)

现在,我假设问题在于,按主键排序的查询执行索引扫描,而按float列排序的查询执行顺序扫描,并且需要在最后进行排序

我认为只要在float列上添加一个索引就足以让Postgresql以更智能的方式规划这个查询。显然我错了。我可能错过了什么


编辑:在发布问题之前,我确实运行了
解释分析。因此,我的假设不仅仅是一种猜测;但是,由于EXPLAIN ANALYZE的输出运行了30多行,因此不清楚为什么一个查询使用索引,而另一个查询必须对所有行进行排序。

对于返回多行的查询,数据库使用非覆盖索引是不寻常的。表查找(从索引到表数据)的成本太高。将改用表扫描

比如说,

select name from people where name > 'N' order by birthdate
数据库会在
(生日)
使用索引吗?从好的方面来说,行将以正确的顺序返回。另一方面,每一行都需要对
name
列进行表查找。第二个要昂贵得多,因此不会使用索引

(生日、姓名)
上的索引不同。它包含名称,因此不需要查找表。数据库可以使用索引以正确的顺序快速返回行

包含查询所需的所有列的索引称为覆盖索引。请确保索引包含查询使用的所有列,然后重试

  • 对查询运行explain analyze-这样您就不必猜测发生了什么
  • 要优化查询,您通常必须阅读解释分析查询的输出,然后找出最佳的操作过程。有时—它添加索引,有时—重写查询。但我们无法判断哪一个最适合您的情况,因为我们既看不到解释也看不到质疑

  • 在没有看到查询的情况下,很难破译正在发生的事情。我的猜测是,查询计划能够基于具有主键的表进行连接,从而保持数据的正确顺序。然后,查询计划基本上是获取一行,在其他表中查找值,对它们进行处理,然后按顺序返回值。处理的范围与
    限制的范围一样远


    当您在
    顺序中用另一列替换该列时,必须处理所有行。这些被分类并返回。它可能是基础表的大小,也可能是导致更长处理时间的结果集的大小。但是,根本原因是需要生成所有行。

    浮点比较将比int比较慢得多。我想你的PK可能是在转移视线。为什么要假设你什么时候可以运行解释分析?@KingCronus。你能证明浮点比较比整数比较慢3600倍吗?“我从来没有经历过这样的性能下降。”戈登林诺夫说得对。我们在这里讨论的是多少行?请通过共享
    解释(分析,缓冲)
    via。Postgres没有聚集索引,从9开始只能使用索引扫描(“覆盖索引”)。2@a_horse_with_no_name:是的,Postgres群集似乎是一次性的,因此它有助于磁盘读取,但不能保证排序不正确“聚集索引”。它只是根据索引重新组织表。这不是自动维护的。此外:返回大量行的查询(与表中的行总数相比)实际上完全不使用索引是非常常见的(例如Postgres中的“seq scan”,Oracle中的“table scan”)@一匹没有名字的马:这正是我在回答这个问题时想表达的观点。实际上,行也不是很多。对于只有100行的行,SQL Server更喜欢表扫描,而不是索引查找。(在SQL Server中,表扫描称为“聚集索引扫描”。)