이중 쿼리 없이 MySQL 페이지 번호 지정
MySQL 쿼리에서 결과 수를 얻는 동시에 결과를 제한하는 방법이 있는지 궁금합니다.
페이지 매김은 처음에 다음과 같은 작업을 수행하는 것으로 알고 있습니다.
query = SELECT COUNT(*) FROM `table` WHERE `some_condition`
num_rows(query)가 있어요. , ㅇㅇㅇㅇㄹㄹㄹㄹㄹㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴ.하지만 실제로 결과를 제한하기 위해 두 번째 질문을 해야 합니다.
query2 = SELECT COUNT(*) FROM `table` WHERE `some_condition` LIMIT 0, 10
제공되는 총 결과 수를 가져오고 단일 쿼리에서 반환되는 결과를 제한할 수 있는 방법이 있습니까?아니면 다른 효율적인 방법이 있을까요?
나는 거의 두 가지 질문을 하지 않는다.
필요한 행보다 하나만 더 반환하고 페이지에 10개만 표시하고 표시된 행보다 많은 행이 있으면 "다음" 버튼을 표시하십시오.
SELECT x, y, z FROM `table` WHERE `some_condition` LIMIT 0, 11
// Iterate through and display 10 rows.
// if there were 11 rows, display a "Next" button.
당신의 질문은 가장 관련성이 높은 순서대로 돌아와야 합니다.대부분의 사람들은 412페이지 중 236페이지로 가는 것에 신경쓰지 않을 것입니다.
구글 검색을 했는데 결과가 첫 페이지에 없으면 9페이지가 아니라 2페이지로 이동합니다.
아니요, 페이지 번호를 매기는 어플리케이션의 수만큼입니다.신뢰성과 방탄성이 뛰어나지만 쿼리를 두 번 실행하지만 카운트를 몇 초 동안 캐시할 수 있으므로 많은 도움이 됩니다.
다른 은 '보다 낫다'를 사용해요.SQL_CALC_FOUND_ROWS합니다.SELECT FOUND_ROWS()거 요.FOUND_ROWS()그 후 콜에 문제가 있습니다.MySQL 에는, 이것에 영향을 주는 버그가 있습니다.ORDER BY큰 테이블에서는 두 쿼리의 단순한 접근 방식보다 훨씬 느립니다.
이중 의 또 다른 을 먼저 두 행만 입니다.COUNT(*)최대 행 수가 검색되었는지 쿼리합니다.
많은 응용 프로그램에서 가장 가능성이 높은 결과는 모든 결과가 한 페이지에 들어맞는 것이며, 페이지 번호 매김은 표준이 아니라 예외입니다.이 경우 첫 번째 쿼리는 최대 수의 결과를 가져오지 않습니다.
예를 들어 Stackoverflow 질문에 대한 답변은 두 번째 페이지에 거의 표시되지 않습니다.답변에 대한 코멘트는 모두 표시하기 위해 필요한 5개 정도를 초과하는 경우가 거의 없습니다.
따라서 이러한 애플리케이션에서는 먼저 LIMIT를 사용하여 쿼리를 수행할 수 있습니다.이 제한에 도달하지 않는 한 몇 개의 행이 있는지 알 수 있습니다.단, 1초도 실행할 필요가 없습니다.COUNT(*)query - 대부분의 상황을 커버합니다.
대부분의 경우 직관에 반하는 것처럼 보이지만 두 개의 개별 쿼리로 수행하는 것이 한 번에 수행하는 것보다 훨씬 빠르고 리소스 소모가 적습니다.
사용하시는 경우SQL_CALC_FOUND_ROWS큰 테이블에서는 쿼리가 매우 느려집니다.두 개의 쿼리를 실행하는 것보다 훨씬 느려집니다.첫 번째 쿼리는COUNT(*)LIMIT가 있는 두 번째.그 이유는SQL_CALC_FOUND_ROWSLIMIT 구를 적용하기 전에 행을 가져오는 대신 LIMIT 구가 적용됩니다.따라서 제한을 적용하기 전에 가능한 모든 결과에 대해 행 전체를 가져옵니다.인덱스는 실제로 데이터를 가져오기 때문에 이 값을 충족할 수 없습니다.
두 가지 쿼리 접근 방식을 사용할 경우 첫 번째 쿼리 접근 방식은 가져오기만 합니다.COUNT(*)실제 데이터를 가져오지 않아도 됩니다. 일반적으로 인덱스를 사용할 수 있고 보는 모든 행에 대해 실제 행 데이터를 가져올 필요가 없기 때문에 훨씬 더 빨리 만족할 수 있습니다.그런 다음 두 번째 쿼리는 첫 번째 쿼리만 보면 됩니다.$offset + $limit행을 지정한 후 돌아갑니다.
MySQL 퍼포먼스 블로그의 이 투고에서는 이에 대해 자세히 설명합니다.
http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
페이지 배정을 최적화하는 방법에 대한 자세한 내용은 이 게시물과 이 게시물을 확인하십시오.
2020년에 답을 찾고 있는 사람들을 위해.MySQL 문서에 따르면:
SQL_CALC_FOUND_ROWS 쿼리 수식자 및 그에 부수되는 FOUND_ROWS() 함수는 MySQL 8.0.17 이후 폐지되며 향후 MySQL 버전에서 삭제될 예정입니다.대체 수단으로 LIMIT을 사용하여 쿼리를 실행하고 다음으로 COUNT(*)를 사용하여 LIMIT을 사용하지 않고 두 번째 쿼리를 실행하여 추가 행이 있는지 여부를 확인합니다.
그걸로 해결됐나 보네
답변이 늦어질 수 있지만 두 번째 쿼리(제한 포함)는 건너뛰고 백엔드 스크립트를 통해 정보를 필터링할 수 있습니다.예를 들어 PHP에서는 다음과 같은 작업을 수행할 수 있습니다.
if($queryResult > 0) {
$counter = 0;
foreach($queryResult AS $result) {
if($counter >= $startAt AND $counter < $numOfRows) {
//do what you want here
}
$counter++;
}
}
그러나 고려해야 할 레코드가 수천 개에 달할 경우 매우 빠르게 비효율적이 됩니다.미리 계산된 카운트를 알아보는 게 좋을 것 같아요
이 주제에 대한 좋은 읽을거리: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf
SELECT col, col2, (SELECT COUNT(*) FROM `table`) / 10 AS total FROM `table` WHERE `some_condition` LIMIT 0, 10
서 ★★★★★10와 「」입니다.0번호입니다. 하면 .pageNumber - 1를 참조해 주세요.
하위 쿼리에서 대부분의 쿼리를 재사용하여 ID로 설정할 수 있습니다.예를 들어, 런타임별로 정렬된 문자 's'가 포함된 동영상을 찾는 동영상 쿼리는 다음과 같습니다.
SELECT Movie.*, (
SELECT Count(1) FROM Movie
INNER JOIN MovieGenre
ON MovieGenre.MovieId = Movie.Id AND MovieGenre.GenreId = 11
WHERE Title LIKE '%s%'
) AS Count FROM Movie
INNER JOIN MovieGenre
ON MovieGenre.MovieId = Movie.Id AND MovieGenre.GenreId = 11
WHERE Title LIKE '%s%' LIMIT 8;
저는 데이터베이스 전문가가 아닙니다.누군가 좀 더 최적화해 주셨으면 합니다.SQL 명령줄 인터페이스에서 바로 실행할 수 있기 때문에 노트북에서는 둘 다 0.02초 정도 걸립니다.
SELECT *
FROM table
WHERE some_condition
ORDER BY RAND()
LIMIT 0, 10
언급URL : https://stackoverflow.com/questions/818567/mysql-pagination-without-double-querying
'programing' 카테고리의 다른 글
| Java Reflection을 사용하여 상속된 속성 이름/값 검색 (0) | 2022.11.05 |
|---|---|
| 테이블을 삭제할 수 없습니다.외부 키 제약에 실패했습니다. (0) | 2022.11.05 |
| 도커가 도커파일을 사용하여 MariaDB에 사용자를 추가하지 않음 (0) | 2022.11.05 |
| php에서 다중 파일 업로드 (0) | 2022.11.05 |
| 봄에 스케줄된 작업을 조건부로 활성화 또는 비활성화하려면 어떻게 해야 합니까? (0) | 2022.11.05 |