Oracle에 의한 페이징
저는 오라클에 대해 제가 원하는 만큼 잘 알지 못합니다.25만 장 정도의 레코드가 있는데 한 장당 100장씩 표시하고 싶습니다.현재 데이터 어댑터, 데이터 어댑터 및 데이터 어댑터를 사용하여 데이터 세트에 대한 25만 개의 레코드를 모두 검색하는 하나의 저장 프로시저가 있습니다.저장된 proc의 결과에 따라 fill(데이터셋) 메서드를 입력합니다.파라미터로 전달할 수 있는 정수값으로 "페이지 번호"와 "페이지당 레코드 수"가 있는 경우 해당 섹션만 반환하는 가장 좋은 방법은 무엇입니까?예를 들어, 페이지 번호로는 10, 페이지 수로는 120을 넘긴다면, 선택 문장에서 1880번째에서 1200번째까지가 됩니다. 제 머릿속 계산은 틀릴지도 모릅니다.
에서 이 작업을 하고 있습니다.NET with C#은 중요하지 않다고 생각했기 때문에 SQL 측에서 바로 얻을 수 있다면 저는 괜찮을 것입니다.
업데이트: Brian의 제안을 사용할 수 있었고, 잘 작동하고 있습니다.최적화 작업을 하고 싶은데, 페이지가 1분이 아니라 4~5초 안에 뜨기 때문에 페이징 컨트롤이 새로운 저장 프로와 매우 잘 통합될 수 있었습니다.
Frans Bouma의 블로그에서 본 내용입니다.
SELECT * FROM
(
SELECT a.*, rownum r__
FROM
(
SELECT * FROM ORDERS WHERE CustomerID LIKE 'A%'
ORDER BY OrderDate DESC, ShippingDate DESC
) a
WHERE rownum < ((pageNumber * pageSize) + 1 )
)
WHERE r__ >= (((pageNumber-1) * pageSize) + 1)
페이지 매김과 매우 유용한 분석 기능에 대해 톰에게 물어보세요.
이 페이지에서 발췌한 내용은 다음과 같습니다.
select * from (
select /*+ first_rows(25) */
object_id,object_name,
row_number() over
(order by object_id) rn
from all_objects
)
where rn between :n and :m
order by rn;
완성도를 높이기 위해 보다 현대적인 솔루션을 찾고 있는 사용자를 위해 Oracle 12c에는 보다 나은 페이징과 톱 핸들링 등 몇 가지 새로운 기능이 있습니다.
페이징
페이징은 다음과 같습니다.
SELECT *
FROM user
ORDER BY first_name
OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY;
상위 N개 레코드
상위 레코드를 얻는 방법은 다음과 같습니다.
SELECT *
FROM user
ORDER BY first_name
FETCH FIRST 5 ROWS ONLY
위의 두 쿼리 예제 모두ORDER BY
절을 참조하십시오.새로운 명령어는 이러한 내용을 고려하여 정렬된 데이터에서 실행됩니다.
적합한 Oracle 참조 페이지를 찾을 수 없습니다.FETCH
또는OFFSET
이 페이지에는 이러한 신기능의 개요가 기재되어 있습니다.
성능
@wweicker가 다음 코멘트에서 지적한 바와 같이 12c의 새로운 구문에서는 퍼포먼스가 문제입니다.이후 Oracle이 개선했는지 테스트할 18c 복사본이 없었습니다.
흥미롭게도 새로운 메서드에 대해 처음 테이블에서 쿼리를 실행했을 때(1억1300만 행 이상) 실제 결과가 약간 더 빨리 반환되었습니다.
- 새로운 방법: 0.013초
- 이전 방식: 0.107초
단, @wweicker가 언급했듯이 새로운 메서드에 대한 설명 계획은 훨씬 더 나빠 보입니다.
- 새로운 방법 비용: 300,110
- 이전 방식 비용: 30
새로운 구문으로 인해 내 컬럼에 있는 인덱스의 전체 스캔이 발생하였고, 전체 비용이 발생하였습니다.인덱스화되지 않은 데이터를 제한하면 상황이 훨씬 악화될 수 있습니다.
이전 데이터 세트에 색인화되지 않은 단일 열을 포함하는 경우를 살펴보겠습니다.
- 새로운 방식 시간/비용: 189.55초/998,908
- 이전 방식 시간/비용: 1.973초/256
개요: Oracle이 이 처리를 개선할 때까지 주의하여 사용하십시오.작업할 인덱스가 있으면 새 방법을 사용할 수 있습니다.
곧 18c를 가지고 놀 수 있고 업데이트 할 수 있기를 바랍니다.
답변과 코멘트를 요약하고 싶을 뿐입니다.페이지 매기기에는 여러 가지 방법이 있습니다.
oracle 12c 이전에는 OFFSET/FETCH 기능이 없었기 때문에 @jasonk가 제안하는 화이트 페이퍼를 참조하십시오.다양한 방법에 대해 장점과 단점을 자세히 설명한 가장 완벽한 기사입니다.복사 붙여넣기에는 상당한 시간이 걸리기 때문에 하지 않겠습니다.
또한 Oracle 및 기타 데이터베이스 페이지 지정과 관련된 몇 가지 일반적인 경고를 설명하는 jooq 크리에이터의 좋은 글도 있습니다.jooq의 블로그 포스트
희소식입니다. Oracle 12c 이후 새로운 OFFSET/FETCH 기능이 추가되었습니다.Oracle Magazine 12c 신기능"상위 N개 쿼리 및 페이지 번호 지정"을 참조하십시오.
다음 명령문을 발행하여 Oracle 버전을 확인할 수 있습니다.
SELECT * FROM V$VERSION
다음을 시도해 보십시오.
SELECT *
FROM
(SELECT FIELDA,
FIELDB,
FIELDC,
ROW_NUMBER() OVER (ORDER BY FIELDC) R
FROM TABLE_NAME
WHERE FIELDA = 10
)
WHERE R >= 10
AND R <= 15;
[tecnicume] 경유
프로젝트에서는 Oracle 12c와 java를 사용했습니다.페이징 코드는 다음과 같습니다.
public public List<Map<String, Object>> getAllProductOfferWithPagination(int pageNo, int pageElementSize, Long productOfferId, String productOfferName) {
try {
if(pageNo==1){
//do nothing
} else{
pageNo=(pageNo-1)*pageElementSize+1;
}
System.out.println("algo pageNo: " + pageNo +" pageElementSize: "+ pageElementSize+" productOfferId: "+ productOfferId+" productOfferName: "+ productOfferName);
String sql = "SELECT * FROM ( SELECT * FROM product_offer po WHERE po.deleted=0 AND (po.product_offer_id=? OR po.product_offer_name LIKE ? )" +
" ORDER BY po.PRODUCT_OFFER_ID asc) foo OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
return jdbcTemplate.queryForList(sql,new Object[] {productOfferId,"%"+productOfferName+"%",pageNo-1, pageElementSize});
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
return null;
}
In SomeServiceClass
using npoco
public async Task<List<SomeModel>> SomeServiceMethod(int pageIndex, int pageSize)
int lowerLimit;
int higherLimit;
//This would help limit the result to 300 max. If the PageSize is stated as 290
//we get the 1st to 289th result. If page size is 1845.
//It returns 1845 - 299 = 1546. 1546th element to 1844th element
if((pageSize) < 300)
{
lowerLimit = 1;
higherLimit = pageSize;
}
else
{
int subtract = 300 - 1;
lowerLimit = pageSize - subtract;
higherLimit = pageSize;
}
//Using Brian Schmitt script
List<SomeModel> someVariableName = db.Query<SomeModel>(SELECT * FROM
(
SELECT a.*, rownum r__
FROM
(
SELECT * FROM ORDERS WHERE CustomerID LIKE 'A%'
ORDER BY OrderDate DESC, ShippingDate DESC
) a
WHERE rownum < (@0)
)
WHERE r__ >= (@1), higherlimit, lowerlimit).ToList();
In SomeControllerClass
[HttpGet]
[Route("SomeControllerMethod")]
public async Task<SomeResponseModel> SomeControllerMethod(int pageIndex, int pageSize)
SomeServiceClass ssc = new SomeServiceClass();
SomeResponseModel srm = new SomeResponseModel();
List<SomeModel> resp = await ssc.SomeServiceMethod(pageIndex, pageSize);
//Paging on API level, solution is from CSharpCorner. This would return a //max of 20 elements per page.
//So if you have a result of 300. It would be divided into 15 pages.
//20 results per page.
int totalRecords = resp.Count();
const int maxPageSize = 20;
pageSize = (pageSize > maxPageSize) ? maxPageSize : pageSize;
int pageNum = pageIndex;
int recordToTake = totalRecords - (pageNum - 1) * pageSize;
int CurrentPage = pageNum;
int TotalPages = (int)Math.Ceiling(totalRecords / (double)pageSize);
var previousPage = CurrentPage > 1 ? "Yes" : "No";
var nextPage = CurrentPage < TotalPages ? "Yes" : "No";
List<SomeModel> filteredResult = resp.Skip((CurrentPage - 1) * pageSize).Take(pageSize).ToList();
srm.records = totalRecords;
srm.previousPage = previousPage;
srm.currentPage = $"Page: {CurrentPage} / {TotalPages}";
srm.nextPage = nextPage;
srm.totalPages = TotalPages;
srm.someIEnumerableProperty = filteredResult;
return srm;
//How to use endpoint
//http://localhost:somePort/someControllerClass/SomeControllerMethod?pageIndex={pageIndex}&pageSize={pageSize}
//pageIndex will take value 1 to 15 since we have a max of 300 and 20 results per page.
//pageSize will be used to determine our higherlimit
언급URL : https://stackoverflow.com/questions/241622/paging-with-oracle
'programing' 카테고리의 다른 글
Bash에 TRY CATCH 명령어가 있습니까? (0) | 2023.04.17 |
---|---|
SQL Management Studio의 시작/끝 블록에서 "스키마 생성"을 사용할 수 없는 이유는 무엇입니까? (0) | 2023.04.17 |
서로 다른 JS 라이브러리에서 생성된 모든 AJAX 요청을 가로채는 방법 (0) | 2023.04.02 |
React와 동등한 TypeScript는 무엇입니까?PropTypes.node? (0) | 2023.04.02 |
Ajax 요청에서 리다이렉트를 검출하고 있습니까? (0) | 2023.04.02 |