【问题标题】:Upgrading a PHP pagination function to run faster升级 PHP 分页功能以更快地运行
【发布时间】:2012-03-26 11:14:30
【问题描述】:

我去年为一个网站文件创建了一个分页,我再也没有真正需要过它。

但是现在我需要在更大的应用程序中使用它,我不知道它在大量 mysql 行的情况下表现不佳。

我将在下面发布一个示例,如果有人能告诉我是否真的需要升级代码,我将不胜感激。

/* Connection file */
include( 'config.php' );

/* Get the amount of all rows */
$mqc = "SELECT COUNT(*) AS total FROM table";
$mqe = mysql_query( $mqc );
$mqn = mysql_fetch_array( $mqe );
$total = $mqn['total'];


/* Rows per page */
$perPage = 10;

/* Range for the pagination */
$range = 5;

/* Actual page */
$page = isset( $_GET['page'] ) &&  
            is_numeric( $_GET['page'] ) && 
            !empty( $_GET['page'] ) ? 
            ( (int)$_GET['page'] * $range ) : 0;

/* Query */
$mqc = "SELECT * FROM table 
            LIMIT " . $page . ", " . $perPage . " ";
$mqe = mysql_query( $mqc );

/* Show results */
while( $l = mysql_fetch_object( $mqe ) )
{
    echo $l->id . ' - ' . $l->title . '<br />';
}

/* Function for pagination */
function pages( $total = false, $perPage = false, $page = false, $range = false )
{
    /* Number of pages */
    $totalPages = ( ceil( $total / $perPage ) ) - 1;
    /* The range * 2 */
    $range = $range;
    /* The real param $_GET['page'] */
    $realGetPage = !empty( $page ) ? ( $page / $range ) : 0;

    /* Show the first page */
    if($realGetPage >= 7)
    {
        echo ' <a href="?page=0"> 1 </a> ... ';
    }

    /* Loop to create the range */
    for($i = ( $realGetPage - $range ); $i < ( $range + $realGetPage ); $i++)
    {
        /* Check out if the value isn't outta range */
        if( $i > 0 && $i < $totalPages )
        {
            /* Highlight the actual page */
            if( ( $i - 1 ) == $realGetPage )
            {
                echo ' [ <a href="?page=' . ( $i - 1 ) . '"> ' . $i . ' </a> ] ';
            }
            else
            {
                echo ' <a href="?page=' . ( $i - 1 ) . '"> ' . $i . ' </a> ';
            }
        }

        /* Store the number of the last page */
        $lastPage = ( $i + 1 );
    }

    /* Hack to show 5678910 */
    if( $lastPage < ( $range * 2 ) + 1 )
    {
        for( $j = $lastPage; $j <= ( $range * 2 ); $j++ )
        {
            if( ($j - 1) == $realGetPage )
            {
                echo ' [ <a href="?page=' . ( $j - 1 ) . '"> ' . $j . ' </a> ] ';
            }
            else
            {
                echo ' <a href="?page=' . ( $j - 1 ) . '"> ' . $j . ' </a> ';
            }
        }

    }

    /* Last page */
    echo ' ...  <a href="?page=' . $totalPages . '"> ' . $totalPages . ' </a> ';
}

/* Show the pagination */
pages( $total, $perPage, $page, $range );

你怎么看?

【问题讨论】:

  • 这看起来像我见过的大多数分页。你有什么具体的担心吗?
  • 我不知道,我从未使用过大型应用程序...我认为它会超过一百万行,还有许多其他巨大的表...所以我会然后使用 INNER 和类似的东西一起选择,你知道..

标签: php mysql performance pagination


【解决方案1】:

根据您在评论中提供的信息,您可能遇到的性能问题不会来自您的 PHP 脚本。如果您在大表上执行多个 INNER JOINS,这正是会影响您的性能的原因。需要注意的一些重要事项:

  • 表索引(如果您使用过滤器,如果您不按主键连接,则用于连接)
  • 优化表/查询以减少 JOIN 数量
  • 如果您预计会有大量流量,请考虑对查询使用缓存(例如 memcached)
  • 正如 Phil 所提到的,必须使用 ORDER BY 来呈现可预测的结果,如果使用表,可能会减慢查询速度。您可以使用 cron 作业预渲染有序表
  • 考虑使用非规范化来减少 JOINS 的数量

【讨论】:

    【解决方案2】:

    我看到缺少的主要内容是ORDER BY 子句。没有这个,你的分页结果(可能)是不可预测的。

    添加一个ORDER BY 子句并确保您在可排序的列上有适当的数据库索引。

    我还建议切换到具有准备好的语句和绑定参数的更新的数据库连接库。请参阅PDO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-21
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多