【问题标题】:How to optimize pagination on a SELECT DISTINCT sql?如何优化 SELECT DISTINCT sql 的分页?
【发布时间】:2014-09-19 10:42:39
【问题描述】:

我的查询是一个非常大的数据库上的一个选择不同,并且在 pgAdmin sql 工具中查询本身持续 12 秒。

SELECT DISTINCT ON (city, airport, zip, country, name) city, airport, price, id FROM mytable;

spring-batch 阅读器定义:

JpaPagingItemReader<MyEntity> reader;
reader.setPageSize(PAGE_SIZE);

如果我将PAGE_SIZE 定义为与数据库列一样大,则性能等于 12 秒。 但是,如果我将大小设置为较低的值(例如,在 1.000.000 数据行 db 上的 pagesize = 100.000),性能会非常糟糕(大约是 10 倍)。

Spring-batch 在后台对查询应用特定的分页。是做什么的:

query.setFirstResult();
query.setMaxResult();

如果页面大小为10,则执行的查询如下:

    firstResult, maxResult
    0, 10
   10, 10
   20, 10
   30, 10...

这再次转换为 SQL 中的 LIMITOFFSET

问题:SELECT DISTINCT ON 不能与分页 LIMIT/OFFSET 结合使用吗?对我来说,似乎每次“分页”运行时都会再次执行完整的选择不同查询,因此会持续很长时间。

那么,如果数据库必须在应用 maxresults 之前进行完全不同的选择,我可以临时保存“不同”选择并只获取下一页吗?

如何改进这一点,而不必将分页大小设置为 100 万。还是这里无法改进?

【问题讨论】:

  • 使用查询分析器查看发生了什么,如果其中有没有索引的列,您可能会遇到麻烦。
  • 我在city, airport, zip, country, name 上有一个索引。
  • 如前所述,使用 pgadmin 工具分析查询的执行(分页和非分页)并查看发生了什么以及花费了这么多时间。在 postgresql 指南中也提到了这一点“OFFSET 子句跳过的行仍然必须在服务器内部计算;因此大的 OFFSET 可能效率低下。”
  • 好的,我看到SELECT DISTINCT ON(..) * FROM.. 的成本很高,但.. ON(..) city FROM.. 的性能很差。因此,我必须将索引作为所选行的组合放置吗?我尝试在选定的列 city, airport, price, id 上放置一个索引,但这并没有改变任何成本......

标签: java sql spring postgresql spring-batch


【解决方案1】:

如果您不使用多个线程来处理此问题,另一种方法是使用JdbcCusorItemReader。这样,您根本不需要优化查询的分页方面。如果您使用多个线程,这不是一个选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2016-08-14
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    相关资源
    最近更新 更多