666개의 Django 프로젝트가 비효율적인 데이터베이스 조회를 검사했습니다.절반이 넘는 사람들이 이 네 가지 반모드를 가지고 있어요.

모든 성숙한 코드 라이브러리는 반모드를 포함한다. 안전한 빈틈을 도입하는 코드 문제, 코드 라이브러리를 사용하는 비용을 증가시키는 기술 채무, 그리고 최선의 실천과 어긋나는 코드는 코드 라이브러리의 운행 속도를 늦춘다.
Django Doctor 정적 분석을 수행하여 이러한 문제를 검색하고 자동으로 해결합니다.우리는 666개의 Django 코드 라이브러리를 검사했는데 저효율의 Django ORM 호출을 발견했고 문제의 심각성에 놀랐다. 우리가 검사한 모든 Django 코드 라이브러리의 50%는 다음과 같은 반모드를 가지고 있다.
  • 16%queryset.count() > 0 대신 queryset.exists() 사용
  • 15% 사용len(queryset) 아님queryset.count()
  • 10% 검사if queryset:가 아니라if queryset.exists():
  • 10%가 외키를 직접 사용하지 않았다
  • 이것은 고작 Django 응용 프로그램의 속도를 떨어뜨릴 뿐만 아니라, 더 나쁜 것은 생산 속도를 떨어뜨릴 것이다.
    이러한 성능 역모드를 어떻게 해결하시겠습니까?해봐our Django performance refactor challenge.
    검사된 Django github 저장소의 절반 이상이 이러한 문제를 안고 있는 것을 감안하면 저장소 중 최소한 하나의 문제가 있을 수 있습니다.경험이 풍부한 Django 개발자는 이런 실수를 범하지 않을 것이라고 생각할 수 있지만 문제는 개발자가 외딴 섬이 아니라는 것이다. 시간이 지날수록 개발자는 팀을 바꾸고 기술 채무를 축적한 갈색 코드 라이브러리를 계승하며 초보 개발자가 작성한 코드를 심사한다.따라서 중요한 것은 다음과 같습니다.
  • 오류 방지
  • 오류를 효과적으로 발견하고 바로잡는 방법을 알고 있음
  • 초보 개발자와 어떻게 소통하는지 아는 것이 왜 문제인지.
  • 사용하다.count () > 0 이 아닙니다.존재()


    비교queryset.count()의 효율은 검사queryset.exists()보다 낮다.Django docs 계수만 있으면 사용하고queryset.count(), 최소한 하나의 결과가 존재하는지 알고 싶으면 사용하라queryset.exists().
    왜냐하면queryset.count() 데이터베이스 테이블의 각 행을 검색하여 합계를 계산하는 SQL 작업이 수행됩니다.다른 한편 queryset.exists()the most optimized way의 레코드 하나만 읽습니다.
  • 주문 삭제
  • 그룹 삭제
  • 쿼리 세트
  • 에서 정의된 모든 개발select_relateddistinct 제거
    그래서
    def check_hounds():
        queryset = HoundsModel.objects.all()
        if queryset.count() > 0:
             return "oh no. Run!"
    
    Django Doctor에서 이 문제를 자동으로 해결합니다.
    def check_hounds():
        queryset = HoundsModel.objects.all()
        if queryset.exists():
             return "oh no. Run!"
    
    Read more

    queryset 대신 len(queryset)을 사용합니다.개수()

    len(queryset) 애플리케이션 레벨에서 실행되는 횟수입니다.이것은doingqueryset.count()보다 효율이 훨씬 낮고 후자는 데이터베이스 단계에서 계산하고 계수만 되돌려준다.
    조회 집합은 lazily evaluated 이다. 이것은 코드와 데이터가 상호작용하기 전에 데이터베이스에서 기록을 읽지 않는다는 것을 의미한다.이것이 바로 우리가 데이터베이스에서 모든 기록을 다운로드하지 않아도 되는 이유이다queryset.all().
    데이터와 상호작용하는 예는doinglen(queryset)이다.이것은queryset의 모든 기록을 읽을 것입니다: 인터넷을 통해 데이터베이스를 효과적으로 다운로드합니다.효율이 특별히 높지 않다.
    한편, Doingqueryset.count()은 SQLSELECT COUNT(*) FROM table과 유사한 SQL을 실행하여 데이터베이스 단계의 계산을 처리한다.이것은 queryset.count()를 사용하면 코드를 더욱 빠르고 데이터베이스 성능을 향상시킬 수 있다는 것을 의미한다.또 5000개의 기록을 다운로드하는 것은 길이를 확인하고 마지막에 버리기 위한 것이 얼마나 낭비인지 생각해 보자.
    그래서
    def check_hounds():
        queryset = HoundsModel.objects.all()
        if len(queryset) > 2:
             return "oh no. Run!"
    
    Django Doctor에서 이 문제를 자동으로 해결합니다.
    def check_hounds():
        if HoundsModel.objects.count() > 2:
             return "oh no. Run!"
    
    그럼에도 불구하고 길이를 검사한 후 기록을 읽어야 한다면 len(queryset) 유효할 수 있습니다.
    Read more

    if-queryset 사용하기:if-queryset이 아닙니다.존재():


    위와 유사하게 데이터베이스 테이블의 모든 줄을 메모리에 불러올 수 있습니다. 왜냐하면 조회 집합은 계산을 거쳤기 때문입니다.조회 집합의 진실/오류 여부를 검사하는 효율은 검사queryset.exists()보다 훨씬 낮다.
    만약 표가 매우 크면 효율이 특히 떨어진다. 그것은 데이터베이스에 있는 CPU의 최고치를 초래하고 웹 서버의 대량의 메모리를 차지할 수 있다.따라서 테이블에서 줄을 추출하지 않고 검사queryset.exists()합니다. 테이블에서 기록을 아주 효과적으로 읽으려고 시도할 뿐입니다.
    그래서
    def check_hounds():
        queryset = HoundsModel.objects.all()
        if queryset:
             return "oh no. Run!"
    
    Django Doctor에서 이 문제를 자동으로 해결합니다.
    def check_hounds():
        queryset = HoundsModel.objects.all()
        if queryset.exists():
             return "oh no. Run!"
    
    Read more

    외키를 직접 사용하지 마라


    외부 키를 사용할 때 방문model_instance.related_field.id은 계산related_field.id에서 데이터베이스를 읽게 됩니다.이것은 Domodel_instance.related_field_id를 통해 제거할 수 있다. 이것은 Django가 이미 대상에 캐시한 키 값으로 이 장면의 효율을 높일 수 있다.
    그래서
    def check_hounds(pk, farm_ids):
        hound = HoundsModel.objects.get(pk=pk)
        if hound.farm.id in farm_ids:
            ...
    
    Django Doctor에서 이 문제를 자동으로 해결합니다.
    def check_hounds(pk, farm_ids):
        hound = HoundsModel.objects.get(pk=pk)
        if hound.farm_id in farm_ids:
          ...
    
    Read more

    Django 코드에는 이러한 역모드가 있습니까?


    시간의 추이에 따라 과학 기술 채무는 너의 코드 라이브러리에 쉽게 빠져들게 된다.django.doctor 또는 review your GitHub PRs를 통해 확인할 수 있습니다.

    아니면 해봐Django refactor challenges.

    좋은 웹페이지 즐겨찾기