sql - 如何通过 order by 降低 sql select 的成本?

标签 sql database postgresql

我正在执行大量的 sql 选择,如下所示。想象一下,我们有一个包含航类的数据库,其中每个航类当然可能有一个出境和入境机场、出发日期、出发地和目的地之间的停靠站数量(长途航类),当然还有价格。

我现在想选择一条特定的路线,并选择停靠次数最少的路线,当然还要选择其中价格最优惠的路线。

CREATE TABLE flights(
    id integer
    outbound character varying,
    inbound character varying,
    date timestamp,
    stops integer
    price numeric
);
CREATE INDEX my_idx ON flights (outbound, inbound, date, stops, price);

select * from flights where outbound = 'SFO' and inbound = 'SYD' and date = '2015-10-10' and stops < 2 order by stops asc, price asc.

问题:使用explain-analyze 的成本相当高:

Sort  (cost=9.78..9.79 rows=1 width=129) (actual time=0.055..0.055 rows=4 loops=1)
  Sort Key: stops, price
  Sort Method: quicksort  Memory: 26kB
  ->  Index Scan using my_idx  (cost=0.42..9.77 rows=1 width=129) (actual time=0.039..0.041 rows=4 loops=1)
        Index Cond: ((date = '2015-10-10'::date) AND ((outbound)::text = 'SFO'::text) AND (stops < 2) AND ((inbound)::text = 'SYD'::text))
Total runtime: 0.079 ms

如果我不间断地按价格排序,成本就可以了 (0.42)。但是按停靠点排序会以某种方式显着增加成本。

如何降低成本?

postgresql 9.3.2

最佳答案

从给定的数字来看,您的替代查询(“如果我不间断地按价格排序”)实际上,并且您误读了数字。 0.079 ms0.42 (?).

这也是有道理的,因为您的第一个查询与索引的排序顺序完全匹配。

您已经有了完美的索引。建议删除price是没有根据的。附加列删除了排序步骤的成本:time=0.055..0.055正如您在计划中看到的那样。

无论哪种方式,它都应该无关紧要。一旦您将检索到的行数减少到一个数(在索引的前导列上使用谓词),无论哪种方式,其余的都是便宜的。

要获得更有趣的结果,请不要使用 stops < 2 进行测试(只留下 0 和 1 个停止点),尝试使用更大的数字来查看任何(可能很小的)差异。

实际上,由于几乎所有列都已经在索引中,我会尝试添加一个缺失的列 id ,也是-如果你能得到index-only scans出于这个(Postgres 9.2+,阅读链接页面上的 Postgres Wiki):

CREATE INDEX my_idx ON flights (outbound, inbound, date, stops, price, <b>id</b>);
SELECT id, outbound, inbound, date, stops, price
FROM ...

关于sql - 如何通过 order by 降低 sql select 的成本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27545743/

相关文章:

mysql,查询条件,如果一个值=任何东西

mysql - 如何在没有选择列的情况下将 MySqlDump 文件导入 MySQL

mysql - SQL 查询 max(), count()

sql 语句,现在 - unix/epoch 时间 6 个月

Postgresql几何圆交集

javascript - Sequelize 得到 N :M association from foreign key

python - 通过SSH隧道访问远程数据库

database - 在 Amazon VM 上上传 Postgres 数据库

PostgreSQL:如何在不使用 "column definition list"的情况下从表中返回动态行?

sql - 使用 SQL 在 Oracle 模式之间复制数据