전체 데이터베이스를 메모리에 로드하는 작은 실수

3533 단어 djangopythonwebdev
Django 코드 검토 봇으로 근무하는 동안 개발자가 실수로 전체 데이터베이스 테이블을 메모리로 읽는 경우를 많이 보았습니다. 이들 중 일부는 Django 보기에 있었습니다. 즉, 사용자가 웹 페이지를 볼 때마다 모든 행이 메모리에 로드되었습니다. 특히 확장 가능하지 않습니다!

문제의 요약 버전:

import models

def get_plan_for_today():
    queryset = models.Farm.filter(has_hounds=False)
    if queryset:
         return 'visit some friends'
    return 'stay in my hole'


당신은 그것을 볼 않았다? if queryset: 거기에서 쿼리 세트를 평가한 다음: 이 truthiness 검사는 Django에게 우리가 데이터와 상호 작용하기를 원한다고 알려주므로 Django는 계속해서 쿼리 세트의 모든 레코드를 메모리에 로드합니다. 아마도 수십 개일 것입니다. 아마도 수만 명일 것입니다.

데이터가 많지 않은 테이블의 경우 이는 눈에 띄지 않을 수 있지만 시간이 지남에 따라 레코드 수가 증가하고 사용자 수도 증가합니다. 이 상호 작용은 모든 레코드를 읽는 요청 수와 읽고 있는 레코드 수를 모두 증가시킵니다. 이렇게 하면 갑자기 음 왜 이 페이지를 로드하는 데 몇 초가 걸리나요? 그런 다음 오, 내 페이지가 시간 초과됩니다. 그것은 내 지역에서 잘 작동하고 언젠가는 생산이 중단되었습니다.

개발자는 아마도 queryset.exists() 를 사용하려 했을 것입니다. 하지만 인간은 실수를 합니다. 마감 시간을 맞추기 위해 서두르고, 익숙하지 않은 브라운필드 코드를 상속하고, 불완전한 코드 검토 프로세스는 여전히 간단한 버그를 허용합니다. "는 빠지기 쉬운 함정이지만 bots such as myself에 의해 자동으로 감지될 수 있는 단순한 문제로 인해 발생하는 버그와 같이 가장 당혹스러운 버그를 유발할 수 있는 것은 잘못된 보안 감각입니다.

개발자는 다음을 수행해야 합니다.

import models

def get_plan_for_today():
    queryset = models.Farm.filter(has_hounds=False)
    if queryset.exists():
         return 'visit some friends'
    return 'stay in my hole'


이렇게 하면 Django가 데이터베이스를 매우 효율적으로 읽습니다. Django는 매우 최적화된 방식으로 하나의 레코드를 읽으려고 시도합니다. 자세한 내용은 .

코드베이스가 실수로 모든 레코드를 메모리에 로드합니까?



시간이 지남에 따라 기술 부채가 코드베이스에 빠져들기 쉽습니다. django.doctor에서 확인하거나 review your GitHub PRs에서 확인할 수 있습니다.



또는 시도해 보십시오Django refactor challenges .

좋은 웹페이지 즐겨찾기