웹 애플리케이션을 개발할 때 Pagination Query는 특히 백엔드 관리 시스템, 댓글 섹션 또는 제품 목록과 같은 모듈에서 매우 일반적인 요구 중 하나입니다. MySQL은 페이징에 대한 한계 조항을 제공하는 반면, PDOSTATEMENT :: rowCount () 메소드는 PHP의 PDO를 사용하여 결과 세트 수를 얻을 수 있습니다. 두 사람이 올바르게 결합되면 코드의 가독성을 향상시킬뿐만 아니라 쿼리 효율을 크게 최적화 할 수 있습니다.
기존의 페이지 매김 쿼리에는 일반적으로 두 단계가 있습니다.
현재 페이지의 데이터를 가져옵니다. 제한 오프셋 사용, count .
총 레코드 수를 얻으십시오 : 테이블에서 Select Count (*)를 사용하십시오.
이 방법은 매우 일반적이지만 데이터 테이블이 클 때 카운트 (*) 의 오버 헤드가 특히 높은 동시성 환경에서 매우 높을 수 있으며, 이는 데이터베이스에 많은 압력을 가할 수 있습니다.
pdostatement :: rowCount () 는 선택 쿼리에서 일치하지 않습니다. 총 레코드 수를 계산하는 데 사용되지 않고 이번에 실행 된 진술에 의해 영향을받는 행 수를 반환하는 데 사용됩니다. Select를 사용하는 경우 일부 데이터베이스 (예 : PostgreSQL)는 쿼리 결과의 행 수를 반환하도록 지원하지만 MySQL에서는 pdo :: mysql_attr_use_buffered_query 옵션이 설정된 경우에만 정확한 결과를 반환 할 수 있습니다.
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass', [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
]);
RowCount ()는 전체를 얻기 위해 완전히 의존 할 수는 없지만 일부 시나리오에서 Pagination 경험을 최적화하기 위해 한계 와 지능형 논리를 결합 할 수 있습니다. 예를 들어, 페이지 당 하나의 데이터를 쿼리하여 다음 페이지가 있는지 확인하여 Count (*) 작업을 피할 수 있습니다.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=exampledb', 'user', 'password', [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
$pageSize = 10;
$offset = ($page - 1) * $pageSize;
$limitPlusOne = $pageSize + 1;
$sql = "SELECT * FROM articles ORDER BY created_at DESC LIMIT :offset, :limit";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':limit', $limitPlusOne, PDO::PARAM_INT);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
$hasNextPage = false;
if (count($results) > $pageSize) {
$hasNextPage = true;
array_pop($results); // 초과분을 제거하십시오
}
// 데이터 렌더링 데이터
foreach ($results as $article) {
echo "<h2>{$article['title']}</h2>";
echo "<p>{$article['summary']}</p>";
echo "<a href=\"https://gitbox.net/articles/{$article['id']}\">전체 텍스트를 읽으십시오</a><hr>";
}
if ($hasNextPage) {
echo "<a href=\"https://gitbox.net/list?page=" . ($page + 1) . "\">다음 페이지</a>";
}
?>
카운트 (*) 쿼리를 피하고 데이터베이스 압력을 줄입니다.
한도 N+1을 사용하여 다음 페이지가 있는지 확인하십시오.
데이터 처리 로직은 간결하고 성능이 좋습니다.
데이터 볼륨이 크고 페이징 깊이가 낮은 시나리오에 특히 적합합니다.
위의 방법은 효율적이지만 모든 상황에 적용 할 수있는 것은 아닙니다. 페이지가 총 페이지 수, 총 레코드 카운트 등과 같은 정보를 표시 해야하는 경우 COUNT (*)를 사용하는 것은 불가피합니다.
$totalCount = $pdo->query("SELECT COUNT(*) FROM articles")->fetchColumn();
$totalPages = ceil($totalCount / $pageSize);
한 가지 타협은 총 정보 수를 캐시하고 매번 실시간 계산을 피하기 위해 정기적으로 새로 고치는 것입니다.
페이징 최적화를 수행 할 때 "일대일에 맞는"모범 사례는 없습니다. 합리적으로 한계를 결합한 RowCount () 및 비즈니스 요구는 고성능 페이징 쿼리의 핵심입니다. 극단적 인 성능을 추구하는 경우 기본 키 또는 타임 스탬프를 기반으로 "커서 기반 페이지 매김"을 고려할 수 있으며, 이는 대규모 데이터 세트에서 더 잘 수행됩니다.
이 기사에 소개 된 팁을 사용하면 대부분의 시나리오에서 비싼 카운트 (*) 쿼리를 피하면서 우수한 사용자 경험과 페이징 정확도를 유지할 수 있습니다.