[mysql] MySQL 데이터-페이징을 구현하는 가장 좋은 방법은 무엇입니까?

내 iPhone 앱은 PHP 웹 서비스에 연결하여 MySQL 데이터베이스에서 데이터를 검색합니다. 요청은 500 개의 결과를 반환 할 수 있습니다.

페이징을 구현하고 한 번에 20 개의 항목을 검색하는 가장 좋은 방법은 무엇입니까?

데이터베이스에서 처음 20 개의 광고를 수신한다고 가정 해 보겠습니다. 이제 다음 20 개의 광고를 요청하려면 어떻게해야합니까?



답변

MySQL 문서에서 :

LIMIT 절을 사용하여 SELECT 문에 의해 리턴되는 행 수를 제한 할 수 있습니다. LIMIT는 하나 또는 두 개의 숫자 인수를 취하는데, 둘 다 음이 아닌 정수 상수 여야합니다 (준비된 명령문을 사용할 때 제외).

두 개의 인수를 사용하면 첫 번째 인수는 반환 할 첫 번째 행의 오프셋을 지정하고 두 번째 인수는 반환 할 최대 행 수를 지정합니다. 초기 행의 오프셋은 0 (1 아님)입니다.

SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

특정 오프셋에서 결과 집합의 끝까지 모든 행을 검색하려면 두 번째 매개 변수에 큰 숫자를 사용할 수 있습니다. 이 명령문은 96 번째 행에서 마지막 행까지의 모든 행을 검색합니다.

SELECT * FROM tbl LIMIT 95,18446744073709551615;

하나의 인수로 값은 결과 세트의 시작 부분에서 리턴 할 행 수를 지정합니다.

SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

즉, LIMIT row_count는 LIMIT 0, row_count와 같습니다.


답변

500 레코드의 경우 효율성은 문제가되지 않지만 수백만 개의 레코드가있는 경우 WHERE 절을 사용하여 다음 페이지를 선택하는 것이 유리할 수 있습니다.

SELECT *
FROM yourtable
WHERE id > 234374
ORDER BY id
LIMIT 20

여기의 “234374”는 이전 페이지에서 본 마지막 레코드의 ID입니다.

그러면 id의 인덱스를 사용하여 첫 번째 레코드를 찾을 수 있습니다. 사용 LIMIT offset, 20하면 페이지 끝까지 갈수록 느리고 느려질 수 있습니다. 내가 말했듯이 200 개의 레코드 만 있으면 문제가되지 않지만 더 큰 결과 집합으로 차이를 만들 수 있습니다.

이 방법의 또 다른 장점은 통화간에 데이터가 변경되면 레코드를 놓치지 않거나 반복되는 레코드를 얻지 못한다는 것입니다. 행을 추가하거나 제거한다는 것은 행이 변경된 후 모든 행의 오프셋을 의미하기 때문입니다. 귀하의 경우에는 중요하지 않을 것입니다-귀하의 광고 풀이 너무 자주 바뀌지 않으며 같은 광고를 두 번 연속해서 얻는 지 아무도 알지 못할 것입니다. 그러나 “가장 좋은 방법”을 찾고 있다면 그런 다음 사용할 방법을 선택할 때 명심해야 할 또 다른 사항입니다.

LIMIT를 오프셋과 함께 사용하려면 (사용자가 페이지를 하나씩 페이징하는 대신 10000 페이지로 직접 이동하는 경우 필요합니다) 큰 으로 LIMIT의 성능을 향상시키기 위해 늦은 행 조회 에 대한이 기사를 읽을 수 있습니다 오프셋.


답변

쿼리에 대해 OFFSET 을 정의하십시오 . 예를 들어

1 페이지-(레코드 01-10) : 오프셋 = 0, 한계 = 10;

페이지 2-(11-20 레코드) 오프셋 = 10, 한계 = 10;

다음 쿼리를 사용하십시오.

SELECT column FROM table LIMIT {someLimit} OFFSET {someOffset};

2 페이지의 예 :

SELECT column FROM table
LIMIT 10 OFFSET 10;


답변

그것에 관한 문헌이 있습니다 :

주요 문제는 큰 사용으로 발생합니다 OFFSET. 이들은 절의 범위 선택에서 일종의 캐싱 또는 사전 계산 페이지에 OFFSET이르기까지 다양한 기술을 사용하지 않습니다 .idWHERE

INDEX 사용, Luke 에는 제안 된 솔루션이 있습니다 .


답변

이 튜토리얼은 페이지 매김을 수행하는 좋은 방법을 보여줍니다.
MySQL을 이용한 효율적인 페이지 매김

즉, OFFSET 또는 큰 LIMIT를 사용하지 마십시오


답변

당신은 또한 할 수 있습니다

SELECT SQL_CALC_FOUND_ROWS * FROM tbl limit 0, 20

테이블 크기를 다시 쿼리 할 필요가 없도록 select 문 (제한없이)의 행 개수는 동일한 select 문에 캡처됩니다. SELECT FOUND_ROWS ()를 사용하여 행 수를 얻습니다.


답변

쿼리 1 : SELECT * FROM yourtable WHERE id > 0 ORDER BY id LIMIT 500

쿼리 2 : SELECT * FROM tbl LIMIT 0,500;

작은 또는 중간 레코드로 쿼리 1을 더 빠르게 실행합니다. 레코드 수가 5,000 이상이면 결과가 비슷합니다.

500 개 레코드에 대한 결과 :

Query1은 9.9999904632568 밀리 초가 걸립니다.

Query2는 19.999980926514 밀리 초가 걸립니다.

8,000 개의 레코드 결과 :

Query1은 129.99987602234 밀리 초가 걸립니다.

Query2는 160.00008583069 밀리 초가 걸립니다.