MongoDB에서 수백만 개의 데이터로 Django 관리자의 성능을 최적화하는 방법

5023 단어 djangopythonmongodb
이 기사에서는 Django admin의 속도를 높여 MongoDB에서 2천만 개 이상의 레코드를 로드할 수 있었던 이전 경험을 공유하고 싶습니다.

문제 정의



쿠버네티스 포드에서 실행되는 MongoDB를 사용하고 Django 관리자와 연결하여 CRUD 작업을 더 쉽게 만들고 사용자 정의 필터링 방법으로 더 나은 검색을 수행했습니다.

문제는 때때로 시간 초과 오류가 발생하여 MongoDB에서 레코드를 느리게 로드하는 것이었습니다. 매일 증가하는 데 사용되는 데이터는 로드를 더욱 악화시킵니다.
또한 Django ORM 자체를 사용하여 MongoDB에 대한 쿼리를 변환하는 Djongo를 사용하고 있습니다.

해결책



이제 성능 저하의 일반적인 이유를 살펴보겠습니다.

인덱싱 DB



일반적으로 MongoDB는 모든 문서를 스캔하여 쿼리와 일치하는지 선택합니다. 수백만 개의 레코드가 있으므로 스캔을 완료하는 데 시간이 오래 걸립니다. 쿼리에서 사용하는 특정 필드를 인덱싱함으로써 MongoDB는 인덱스를 사용하여 검사해야 하는 문서 수를 제한할 수 있습니다.

현재 문제에 대한 정확한 해결책을 고민하고 있기 때문에 자세한 내용은 documentation에서 확인하실 수 있습니다.
  • 필터링에 사용 중인 필드에 대한 인덱스를 생성해야 합니다.
  • 필터링에 여러 필드가 포함된 경우 compound indexes 생성을 고려하십시오.

  • 인덱스는 문서 자체와 별도로 컬렉션의 문서에 보관된 데이터의 작은 하위 집합을 저장하는 특수 데이터 구조입니다. 따라서 메모리(RAM) 성능을 확인하고 필요에 따라 늘려야 합니다.

    사용자 정의 페이지네이터



    Django admin은 기본적으로 레코드 수를 세고 해당 페이지네이터를 생성하는 페이지네이션을 사용합니다. 이때는 카운트가 끝날 때까지 기다리는 시간이 많이 걸립니다.

    먼저 count 클래스의 Paginator 속성을 살펴보겠습니다.

        @cached_property
        def count(self):
            """Return the total number of objects, across all pages."""
            c = getattr(self.object_list, 'count', None)
            if callable(c) and not inspect.isbuiltin(c) and method_has_no_args(c):
                return c()
            return len(self.object_list)
    


    이제 카운트가 필요하지 않으므로 실제 카운팅을 건너뛰어 기본 기능을 재정의하는 사용자 지정 페이지네이터를 만들어 보겠습니다.

    admin.py

    from django.core.paginator import Paginator
    
    
    class NoCountPaginator(Paginator):
        @property
        def count(self):
            return 999999999
    


    또한 setting show_full_result_count ~ False까지 전체 개수를 표시하기 위해 필터링된 페이지에서 개수 쿼리를 비활성화하는 목록 형식의 개수를 방지해야 합니다.

    *admin.py
    *

    @admin.register(models.Mymodel)
    class MymodelAdmin:
    
        paginator = NoCountPaginator
        show_full_result_count = False
    


    사용자 지정 필터링



    이것은 이전에 구현할 수 있는 Django 관리에서 사용자 정의 필터링 기능(list_filter)을 확인하기 위한 추가 경고입니다. 제 경우에는 모든 문서에서 고유한 값을 가져오는 데 사용되는 필드가 있었습니다. 문서 수가 증가함에 따라 성능이 극도로 느려집니다.

    솔루션으로 모든 문서를 스캔하고 필터링을 위해 특정 값을 가져오는 대신 텍스트 상자 검색으로 대체할 수 있습니다.

    건너뛰기 및 제한 사용 안 함



    쿼리에서 오프셋을 사용하면 성능이 변경되지 않지만 이전보다 훨씬 느려질 수 있습니다. 오프셋을 선언하고 있으므로 MongoDB는 특정 문서에 도달할 때까지 모든 문서를 검토합니다. 처음 몇 페이지는 빠를 수 있지만 오프셋이 클수록 성능이 느려집니다.

    Original Post

    좋은 웹페이지 즐겨찾기