데이터베이스의 결과 페이지화는 어떻게 작동합니까?
이 질문은 MySQL, Oracle DB 또는 기타 다른 모든 항목에 적용되는 일반적인 질문입니다.
MySQL에는 LIMIT 오프셋, 크기가 있고 Oracle에는 'ROW_NUMBER' 등이 있습니다.
그러나 이러한 '페이징된' 쿼리가 연속적으로 호출될 때, 데이터베이스 엔진은 실제로 전체 '선택'을 처음부터 다시 수행한 다음 매번 다른 결과의 하위 집합을 검색합니까?아니면 전체적인 결과 가져오기를 한 번만 수행하고 결과를 메모리 등에 저장한 다음 오프셋 및 크기를 기반으로 한 후속 쿼리에 대해 결과의 하위 집합을 제공합니까?
매번 전체 가져오기를 수행하면 상당히 비효율적인 것 같습니다.
전체 가져오기를 한 번만 수행하는 경우 쿼리를 어딘가에 '저장'해야 합니다. 그러면 쿼리가 다음에 들어올 때 이미 모든 데이터를 가져왔고 다음 페이지를 추출하기만 하면 됩니다.이 경우 데이터베이스 엔진은 여러 스레드를 어떻게 처리합니까?동일한 쿼리를 실행하는 두 개의 스레드?
저는 매우 혼란스럽습니다 :(
저는 @Bill Karwin의 의견에 동의하지 않습니다.우선 측정을 하지 않고 무엇인가가 빠를지, 느릴지 미리 추측하지 말고, '더 빠를 것 같다'는 이유로 코드를 복잡하게 만들어 한 번에 12페이지를 내려받아 캐시에 저장합니다.
YAGNI 원칙 - 프로그래머는 필요하다고 판단될 때까지 기능을 추가해서는 안 됩니다.
가장 간단한 방법(한 페이지의 일반 페이지)으로 작업하고, 프로덕션에서 작동하는 방식을 측정한 다음, 속도가 느리면 다른 방법을 시도하고, 속도가 만족스러우면 그대로 둡니다.
약 80,000개의 레코드가 포함된 테이블에서 데이터를 검색하는 응용 프로그램에서 메인 테이블은 4-5개의 추가 조회 테이블과 결합되고, 전체 쿼리는 페이지 당 약 25-30개의 레코드, 총 2500-3000페이지입니다.데이터베이스는 Oracle 12c이며, 몇 개의 열에 인덱스가 있으며, 최대 절전 모드에서 쿼리가 생성됩니다.서버 측 프로덕션 시스템에서 측정한 결과, 한 페이지를 검색하는 데 걸리는 평균 시간(중앙값 - 50% 백분위수)은 약 300ms입니다.95% 백분위수는 800ms 미만입니다. 즉, 단일 페이지 검색 요청의 95%가 800ms 미만입니다. 서버에서 사용자에게 전송하는 시간과 약 0.5-1초의 렌더링 시간을 추가하면 총 시간이 2초 미만입니다.이제 충분합니다. 사용자들은 행복합니다.
그리고 일부 이론 - 페이지화 패턴의 목적이 무엇인지 알기 위해 이 답변을 참조하십시오.
예, 쿼리를 다른 OFFSET으로 실행하면 쿼리가 다시 실행됩니다.
네, 이것은 비효율적입니다.큰 결과 집합을 페이지로 이동해야 하는 경우에는 이 작업을 수행하지 마십시오.
10페이지 또는 12페이지 분량의 큰 제한을 두고 한 번 쿼리를 수행하는 것이 좋습니다.그런 다음 결과를 캐시에 저장합니다.사용자가 여러 페이지를 진행하려고 할 때 응용 프로그램은 캐시에 저장한 10-12 페이지를 가져와 사용자가 보고 싶은 페이지를 표시할 수 있습니다.일반적으로 각 페이지에 대해 SQL 쿼리를 실행하는 것보다 훨씬 빠릅니다.
이것은 대부분의 사용자와 마찬가지로 사용자가 몇 페이지만 읽은 다음 쿼리를 변경하는 경우에 잘 작동합니다.
댓글:
캐시란 Memcached나 Redis 같은 것을 말합니다.고속 메모리 내 키/값 저장소입니다.
MySQL 보기는 아무것도 저장하지 않으며, 사용자를 위해 미리 정의된 쿼리를 실행하는 매크로에 가깝습니다.
Oracle은 구체화된 보기를 지원하므로 더 효과적으로 작동할 수 있지만 보기를 쿼리하면 SQL 쿼리를 해석하는 오버헤드가 발생합니다.
단순한 메모리 내 캐시가 훨씬 빠를 것입니다.
언급URL : https://stackoverflow.com/questions/50846643/how-does-pagination-of-results-in-databases-work
'programing' 카테고리의 다른 글
Angular2 http 서비스를 사용하여 결과 캐싱 (0) | 2023.09.05 |
---|---|
MariaDB 마스터에서 마스터로의 복제 자동 증분이 순차적이지 않음 (0) | 2023.09.05 |
두 CG 지점 사이의 거리를 찾는 방법은 무엇입니까? (0) | 2023.09.05 |
깃 별칭을 삭제하려면 어떻게 해야 합니까? (0) | 2023.09.05 |
Stop-Service Cmdlet이 존재하는 서비스를 열 수 없습니다. (0) | 2023.09.05 |