代码之家  ›  专栏  ›  技术社区  ›  Martin

使用SQL查询时,最有效的方法是什么?

  •  0
  • Martin  · 技术社区  · 16 年前

    我正在尝试将SQL查询的结果分页,以便在网页上使用。语言和数据库后端是php和sqlite。

    我使用的代码的工作方式类似于此(页码从0开始)

    http://example.com/table?page=0

    page = request(page)
    per = 10 // results per page
    offset = page * per
    
    // take one extra record so we know if a next link is needed
    resultset = query(select columns from table where conditions limit offset, per + 1)
    
    if(page > 0) show a previous link
    if(count(resultset) > per) show a next link
    
    unset(resultset[per])
    
    display results
    

    有没有比这更有效的方法来进行分页?

    当前方法中的一个问题是,在开始显示结果之前,必须将所有10个(或多个)结果存储在内存中。我这样做是因为PDO不能保证行数可用。

    发行A更有效吗 COUNT(*) 查询以了解存在多少行,然后将结果流式传输到浏览器?

    这是其中之一吗?这取决于你的桌子的大小,以及 count(*) 查询需要在数据库后端进行完整的表扫描,“自己做一些分析”之类的问题?

    4 回复  |  直到 7 年前
        1
  •  1
  •   Owen Ryan Doherty    16 年前

    我建议你先数数。计数(主键)是一个非常有效的查询。

        2
  •  2
  •   Martin    16 年前

    我选择使用count(*)双查询方法,因为它允许我直接创建到最后一页的链接,而另一个方法不允许这样做。首先执行计数还允许我对结果进行流式处理,因此对于内存较少的记录数较多的情况应该可以很好地工作。

    页面之间的一致性对我来说不是问题。谢谢你的帮助。

        3
  •  2
  •   Wayne    16 年前

    在一些情况下,我有一个相当复杂的(9-12表联接)查询,返回数千行,我需要对这些行进行分页。很明显,为了很好地分页,您需要知道结果的总大小。使用MySQL数据库,使用select中的sql_calc_found_rows指令可以帮助您轻松实现这一点,尽管这是否对您更有效还不得而知。

    但是,由于您使用的是sqlite,我建议您坚持使用2查询方法。 Here 这是一个非常简洁的话题。

        4
  •  1
  •   Troels Arvin    16 年前

    我怀疑对于您的用户来说,等待后端返回10行是一个问题。(您可以通过擅长指定图像尺寸、使Web服务器在可能时协商压缩数据传输等来弥补这些不足。)

    我不认为这将是非常有用的为您做一个计数(*)开始。

    如果您正在进行一些复杂的编码:当用户查看第X页时,使用类似Ajax的魔力预加载第X+1页以改善用户体验。

    关于分页的一般注释: 如果用户浏览页面时数据发生变化,则 可以 如果您的解决方案要求非常高的一致性,那么就成为一个问题。我已经写了一封信 elsewhere .