이 기사는 Ma Le가 Huawei 클라우드 커뮤니티에서 공유한 " 애플리케이션의 대용량 데이터 페이징 처리 "입니다.
소개
많은 양의 데이터를 표시하는 것은 항상 해결해야 할 문제로 간주되어 왔습니다. 고전적인 아이디어는 일괄적으로 표시하고 처리하는 것입니다.
1 쿼리 중 외래 키 처리
모델이 Django 모델에서 외래 키를 사용하는 경우 on_delete를 통해 관련 작업을 정의합니다.
CASCADE: 캐스케이드 동작. 외래 키 데이터가 삭제되면 이 데이터도 삭제됩니다. PROTECT: 보호됨. 이 데이터가 외래 키의 데이터를 참조하는 한 외래 키 데이터를 강제로 삭제하면 Django 프레임워크에서 오류를 보고합니다. SET_NULL: NULL로 설정됩니다. 외래 키 데이터가 삭제되면 이 데이터는 NULL로 설정됩니다. 단, 이 데이터는 NULL로 설정될 수 있습니다. SET_DEFAULT: 기본값을 설정합니다. 외래 키 데이터가 삭제된 경우 기본값이 있는 경우 이 데이터의 값을 기본값으로 설정합니다. SET() 함수: 외래 키의 데이터가 삭제되면 SET 함수의 값을 외래 키의 값으로 가져옵니다. Set() 함수는 호출 가능 객체를 허용할 수 있으며 호출 가능 객체의 반환 값은 결과로 다시 설정됩니다. DO_NOTHING: 어떤 조치도 취하지 않습니다. 모든 것은 데이터베이스 수준 동작에 따라 다릅니다.
데이터베이스 수준 제약조건:
PESTRICT: 기본 옵션으로, 상위 테이블 레코드를 삭제하려는 경우, 하위 테이블에 관련 레코드가 있으면 삭제가 허용되지 않습니다. NOACTION: 위와 동일합니다. 먼저 외래 키를 감지합니다. CASCADE: 상위 테이블이 삭제 및 업데이트되면 하위 테이블 연결 작업도 삭제 및 업데이트됩니다. SET NULL: 상위 테이블이 삭제되거나 업데이트될 때 하위 테이블은 연관된 레코드의 외래 키 필드를 null로 설정하므로 하위 테이블 설계 시 null이 될 수 없습니다.
이러한 외래 키 방법 도구는 사용자가 다중 테이블 관련 쿼리 작업을 처리하는 데 도움이 될 수 있습니다.
1.1 django에서 페이지 매김을 쿼리하는 방법
페이징 쿼리가 있는 애플리케이션에서는 LIMIT 및 OFFSET을 포함한 쿼리가 매우 일반적이며 거의 모든 쿼리에 ORDER BY 절이 있습니다.
인덱스 정렬을 사용하면 성능 최적화에 매우 도움이 됩니다. 그렇지 않으면 서버에서 많은 파일 정렬을 수행해야 합니다.
고주파수 문제는 오프셋 값이 너무 크다는 것입니다. 쿼리가 LIMIT 10000, 20과 같은 경우 10020개의 행이 생성되고 이전 10000개의 행은 삭제되므로 비용이 매우 많이 듭니다.
ID 제한 10000, 20으로 테이블 순서에서 *를 선택합니다.
이 문의 의미는 10000+20개의 레코드를 쿼리하고 처음 10000개의 레코드를 제거하고 마지막 20개의 레코드를 반환하는 것입니다.
이 쿼리가 페이징을 달성할 수 있다는 것은 의심의 여지가 없지만 MySQL은 10000+20 레코드를 모두 스캔해야 하기 때문에 값이 10000이 클수록 쿼리 성능이 저하됩니다.
모든 페이지가 동일한 빈도로 액세스된다고 가정하면 이러한 쿼리는 평균적으로 데이터 테이블의 절반을 검색합니다. 이를 최적화하려면 페이지를 매긴 보기에서 액세스할 수 있는 최대 페이지 수를 제한하거나 대규모 일괄 쿼리를 더 효율적으로 만들 수 있습니다.
테이블에 쿼리 조건을 만족하는 데이터가 많은 경우, 한꺼번에 다 꺼낼 필요가 없는 경우가 많아 쿼리 효율성이나 서버 성능에 큰 어려움을 겪게 됩니다. 예를 들어 가장 간단한 쇼핑몰의 경우, 쇼핑몰에 10,000개의 데이터가 있지만 프런트 엔드에서는 한 번에 한 페이지만 볼 수 있다고 가정합니다.
xxx="xxx"가 10으로 제한되는 테이블에서 *를 선택합니다.
조건에 맞는 10개의 데이터를 조회한다는 의미입니다.
xxx="xxx"가 10 오프셋 10을 제한하는 테이블에서 *를 선택합니다.
조건에 맞는 11번째부터 20번째까지의 데이터를 조회하는 페이징(Paging)을 의미합니다.
또는 최대 ID를 지정하여 쿼리
id > #max_id# 순서가 id 제한 n인 테이블에서 *를 선택합니다.
이 쿼리도 마지막 n개의 레코드를 반환하지만 방법 1처럼 처음 m개의 레코드를 스캔할 필요는 없지만 각 쿼리에서 이전 쿼리(이전 페이지)의 최대 ID(또는 최소 ID)를 얻어야 합니다. 방식이 더 일반적으로 사용됩니다.
물론 이 쿼리의 문제점은 최대 ID가 연속적이지 않으면 ID를 얻지 못할 수도 있다는 것입니다. 예를 들어 현재 3페이지에 있고 5페이지의 데이터를 쿼리해야 한다면 작동하지.
또는 하위 쿼리를 통해 먼저 처음 10,000개를 필터링하고 가장 큰 ID를 찾은 다음 요구 사항을 충족하는 나머지 20개를 선택합니다.
id > (id 제한 m, 1로 테이블 순서에서 id 선택) n 제한;
이 쿼리도 테이블 연결이 필요하지 않으므로 하위 쿼리를 통해 필드 ID를 검색하지만, 이는 이전 페이지의 최대 ID를 알 수 없는 경우에 권장되는 사용법입니다.
좌우 연결 방식 자체가 성능이 저하될 수 있습니다.
다음 하위 쿼리도 있으며, 테이블을 조인하고, 인덱스를 추가하여 튜플을 빠르게 찾은 다음 튜플을 읽습니다.
SELECT * FROM 테이블 WHERE id <= (SELECT id FROM 테이블 ORDER BY id DESC LIMIT (페이지-1)*페이지 크기 ORDER BY id DESC LIMIT 페이지 크기)
Rest_framework에는 페이징 작업 모듈이 내장되어 있습니다. Employee/views.py의 특정 기능에 적용해 보겠습니다.
Rest_framework.pagination에서 PageNumberPagination 가져오기 @api_view(['GET', 'POST']) @permission_classes([사용자 정의권한]) def blog_api_view(요청): """""" request.method == "GET"인 경우: 페이지네이터 = PageNumberPagination() # paginator.page_size = 1 설정으로 페이지당 항목 1개만 표시합니다. paginator.page_size = 2 task_objects = EmployeeSign.objects.all() 결과 = paginator.paginate_queryset(task_objects, 요청)
페이징을 사용하지 않으면 모든 메시지가 동일한 페이지에 표시됩니다.
serializer = TaskSerializer(결과, 많음=True) 응답(serializer.data) 반환
페이징 데이터에 액세스합니다. 기본 인터페이스 http://127.0.0.1:2001/api/tasks/는 페이징 1입니다.
http://127.0.0.1:2001/api/tasks/?page=1 #2,3,4...
2 요약
다시 말하지만, 페이지가 매겨진 쿼리가 있는 애플리케이션에서는 LIMIT 및 OFFSET이 포함된 쿼리가 매우 일반적이며 거의 모든 쿼리에 ORDER BY 절이 있습니다. 인덱스 정렬을 사용하면 성능 최적화에 매우 도움이 됩니다. 그렇지 않으면 서버에서 많은 파일 정렬을 수행해야 합니다.
고주파수 문제는 오프셋 값이 너무 크다는 것입니다. 쿼리가 LIMIT 10000, 20과 같은 경우 10020개의 행이 생성되고 이전 10000개의 행은 삭제되므로 비용이 매우 많이 듭니다.
모든 페이지가 동일한 빈도로 액세스된다고 가정하면 이러한 쿼리는 평균적으로 데이터 테이블의 절반을 검색합니다.
이를 최적화하려면 페이지를 매긴 보기에서 액세스 가능한 최대 페이지 수를 제한하거나 대규모 쿼리를 보다 효율적으로 만들 수 있습니다.
화웨이 클라우드의 신기술에 대해 빨리 알아보고 팔로우하려면 클릭하세요~
JetBrains 2024(2024.1)의 첫 번째 메이저 버전 업데이트는 오픈소스 인데 Microsoft도 비용을 지불할 계획인데 아직도 오픈소스라는 비판을 받는 이유는 무엇일까요? [복구] Tencent Cloud 백엔드 충돌: 콘솔에 로그인한 후 많은 서비스 오류가 발생하고 데이터가 없습니다. 독일도 "독립적으로 제어 가능"해야 합니다. 주 정부는 30,000대의 PC를 Windows에서 Linux deep-IDE로 마이그레이션하여 마침내 달성했습니다. 부트스트래핑! Visual Studio Code 1.88이 출시되었습니다. Tencent는 Switch를 "생각하는 학습 기계"로 전환했습니다. RustDesk 원격 데스크톱이 시작되고 웹 클라이언트를 재구성합니다. WeChat의 SQLite 기반 오픈 소스 터미널 데이터베이스인 WCDB가 크게 업그레이드되었습니다.