代码之家  ›  专栏  ›  技术社区  ›  Ty W

以编程方式替换sql查询中的SELECT字段,以确定结果数量

  •  0
  • Ty W  · 技术社区  · 16 年前

    对于任何查询(分组、连接和子查询都可以以任何组合的方式进行),我想尽可能有效地用分页来分解它。现在我只运行查询,然后计算返回给PHP的行数,计算出有多少页数据,显示当前页面上的数据,并输出到其他页面的正确链接。

    然而,在我看来,查询可能产生的非常大的结果集大多被浪费了。有没有一种方法可以运行两次查询,第一次选择COUNT(*)以获取包含要分页的行的单个数字,第二次根据当前查看的页面以适当的限制运行原始查询?这会大大减轻数据库服务器的负担吗?

    对于一个微不足道的查询,这不是问题。..将SELECT之后和WHERE之前的所有内容替换为count(*)。但是,如果查询中有分组,则这不起作用,因为您将获得每个组中的计数,而不是总行数。如果您对列a、b和c进行分组,选择count(不同于a、b、c)是否正确?处理子查询需要做什么特殊的事情吗?

    5 回复  |  直到 16 年前
        1
  •  4
  •   Paul Dixon    16 年前

    SQL_CALC_FOUND_ROWS 给你一个小的结果集,同时让MySQL计算无限结果集的大小:

    SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name LIMIT 10;
    
    SELECT FOUND_ROWS();
    
        2
  •  3
  •   Arvo    16 年前

    select count(*)
    from (<original select query>)
    
        3
  •  2
  •   Mercer Traieste    16 年前

    这可能会有所帮助:mysql有 限制 特点:

    select * 
    from mytable
    limit 10,40
    

    哪里 限制10,40 意味着从结果10(以0为基础)开始给我40个结果。

    您可以在此功能上构建分页。在上述示例中,40表示每页40个结果。

        4
  •  2
  •   Edward Dale    16 年前

    您可以让mySQL使用DateTimeCALC_OUND_rows计算在没有限制子句的情况下返回的行数。

    这将给你20页的第一页:

    SELECT SQL_CALC_FOUND_ROWS * FROM table LIMIT 0,20
    

    然后,您可以询问在没有_RESCALC_FUND_rows的情况下返回的行数:

    SELECT FOUND_ROWS() AS numrows
    

    这将在驱动程序内得到回答,而无需向数据库服务器发出另一个请求。它还应该适用于更复杂的查询。

        5
  •  0
  •   J. Polfer    16 年前

    我会在你的开发环境中做一些实验,看看是否有任何性能优势。

    您可以使用MercerTraieste建议的limit子句根据每页记录限制返回结果,但是,您现在每页都要访问数据库,这通常是要避免的。我假设你的PHP脚本使用游标从MySQL服务器获取数据,我想游标保持打开状态,为你的其他页面检索数据。 通过执行LIMITed查询,您实际上可能会对数据库服务器征税更多 当然,我会通过使用MySQL性能监控工具(如果有的话)监控数据库负载来进行测试/实验。

    您可能甚至不需要执行COUNT(*)来对它们进行分页,只需确定每页需要多少条记录,然后从不同的结果点开始返回它们。

    即,do(伪代码如下)

    SELECT <columns> FROM <table> LIMIT <records-per-page>;
    while (More data available for future pages)
    {
        records-shown += records-per-page;
        SELECT <columns> FROM <table> LIMIT <records-per-page>,<records-shown>;
    }
    

    诚然,其他方法可能更清洁。