【问题标题】:Two questions on PostgreSQL performance关于PostgreSQL性能的两个问题
【发布时间】:2013-03-23 21:19:54
【问题描述】:

1) 在 PostgreSQL 中实现分页的最佳方式是什么?

假设我们需要实现分页。最简单的查询是select * from MY_TABLE order by date_field DESC limit 10 offset 20据我了解,我们这里有两个问题:如果日期可能有重复的值,则每次运行此查询可能会返回不同的结果,并且偏移值越大,查询运行的时间就越长。我们必须提供额外的列,即 date_field_index:

--date_field--date_field_index--
  12-01-2012     1
  12-01-2012     2
  14-01-2012     1
  16-01-2012     1
--------------------------------

现在我们可以写类似的东西

create index MY_INDEX on MY_TABLE (date_field, date_field_index);
select * from MY_TABLE where date_field=<last_page_date and not (date_field_index>=last_page_date_index and date_field=last+page_date) order by date_field DESC, date_field_index DESC limit 20;

..因此使用 where 子句和相应的索引而不是偏移量。好的,现在是问题:

1) 这是改进初始查询的最佳方法吗? 2) 我们如何填充 date_field_index 字段?我们必须为此提供一些触发器吗? 3) 我们不应该在 Postgres 中使用 RowNumber() 函数,因为它们不使用索引,因此非常慢。对吗?

2) 为什么连接索引中的列顺序不会影响查询的性能?

我的测量结果表明,在使用连接索引(由 2 列或更多列组成的索引)进行搜索时,如果我们将最具选择性的列放在首位 - 或者将其放在末尾,则没有区别。为什么?如果我们将最具选择性的列放在第一位 - 我们会遍历更短范围的找到的行,这应该会对性能产生影响。我说的对吗?

【问题讨论】:

    标签: sql performance postgresql pagination


    【解决方案1】:

    使用主键解开而不是date_field_index列。否则请解释为什么这不是一个选项。

    order by date_field DESC, "primary_key_column(s)" DESC
    

    具有最独特列的组合索引性能最佳,但在以下情况下将不会使用它:

    • 不同的值超过表格的百分之几
    • 没有足够的行来使其值得
    • 日期范围不够小

    explain my_query 的输出是什么?

    【讨论】:

    • Clodoaldo Neto,我不知道如何编写按日期获取行但按主键排除已经获取的行的查询。请给我一个例子。如果主索引的顺序与日期字段的顺序一致,这可能会起作用,即在插入 12-May、13-May、14-May 时,我们还将 primary_index 设置为 45、46、47 而不是 45、47、46,而是以保证这是一项单独的任务。
    • @Kuta 你的意思是每次约会只需要一行?如果是这样,解绑标准是什么?它可以是主键顺序中的第一个吗?您必须提供表结构才能构建分组查询。
    • 在我的数据库中,一行有一个日期列,但几行可能有相同的日期列值。您建议创建一个由唯一 id 列和 date 列组成的连接索引?好的,但是请写下整个分页查询。假设该表由 2 个字段组成:日期和唯一的 int id。
    猜你喜欢
    • 1970-01-01
    • 2015-09-16
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 2022-09-24
    • 2011-09-19
    相关资源
    最近更新 更多