>  기사  >  백엔드 개발  >  Django의 QuerySet을 효과적으로 사용하기

Django의 QuerySet을 효과적으로 사용하기

巴扎黑
巴扎黑원래의
2017-04-05 15:05:571903검색

ORM(객체 관계형 매핑)을 사용하면 SQL 데이터베이스와의 상호 작용이 더 간단해지지만 원시 SQL보다 비효율적이고 느린 것으로 간주됩니다.

ORM을 효과적으로 사용한다는 것은 ORM이 데이터베이스를 쿼리하는 방법을 이해하는 것을 의미합니다. 이 기사에서는 Django ORM 시스템을 효과적으로 사용하여 중대형 데이터 세트에 액세스하는 방법에 중점을 둘 것입니다.

Django의 쿼리셋은 게으르다

Django의 쿼리 세트는 선택적 쿼리를 통해 필터링된 데이터베이스의 여러 레코드(행)에 해당합니다. 예를 들어, 다음 코드는 데이터베이스에서 'Dave'라는 이름의 모든 사람을 가져옵니다.

person_set = Person.objects.filter(first_name="Dave")

위의 코드는 데이터베이스 쿼리를 실행하지 않습니다. person_set을 사용하거나 여기에 일부 필터 조건을 추가하거나 함수에 전달할 수 있으며 이러한 작업은 데이터베이스로 전송되지 않습니다. 이는 데이터베이스 쿼리가 웹 애플리케이션의 성능에 큰 영향을 미치는 요소 중 하나이기 때문에 맞습니다.

실제로 데이터베이스에서 데이터를 가져오려면 queryset:

for person in person_set:
    print(person.last_name)

를 순회해야 합니다. Django의 쿼리셋에는 캐시가 있습니다

쿼리 세트를 반복하면 일치하는 모든 레코드가 데이터베이스에서 검색되어 Django 모델로 변환됩니다. 이것을 평가라고 합니다. 이러한 모델은 쿼리 세트의 내장 캐시에 저장되므로 쿼리 세트를 다시 반복하는 경우 동일한 일반 쿼리를 다시 실행할 필요가 없습니다.

예를 들어 다음 코드는 데이터베이스 쿼리를 한 번만 실행합니다.

pet_set = Pet.objects.filter(species="Dog")
# The query is executed and cached.
for pet in pet_set:
    print(pet.first_name)
# The cache is used for subsequent iteration.
for pet in pet_set:
    print(pet.last_name)

if 문은 쿼리 세트

실행을 트리거합니다. 쿼리 세트 캐시의 가장 유용한 점은 쿼리 세트에 데이터가 포함되어 있는지 여부를 효과적으로 테스트할 수 있다는 것입니다.

restaurant_set = Restaurant.objects.filter(cuisine="Indian")
# `if`语句会触发queryset的执行。
if restaurant_set:
    # 遍历时用的是cache中的数据
    for restaurant in restaurant_set:
        print(restaurant.name)

모든 데이터가 필요하지 않다면 쿼리셋 캐시가 문제가 될 수 있습니다

때로는 모든 데이터를 순회하지 않고 데이터가 존재하는지 여부만 알고 싶을 수도 있습니다. 이 경우 단순히 if 문을 사용하여 판단하면 데이터가 필요하지 않더라도 전체 쿼리 세트가 완전히 실행되고 데이터가 캐시에 저장됩니다!

아아아아

이를 방지하려면 presents() 메소드를 사용하여 데이터가 있는지 확인할 수 있습니다:

city_set = City.objects.filter(name="Cambridge")
# `if`语句会执行queryset.。
if city_set:
    # 我们并不需要所有的数据,但是ORM仍然会获取所有记录!
    print("At least one city called Cambridge still stands!")

쿼리셋이 너무 크면 캐시가 문제가 됩니다

수천 개의 레코드를 처리할 때 한꺼번에 메모리에 로드하는 것은 낭비입니다. 더 나쁜 것은 거대한 쿼리 세트가 시스템 프로세스를 잠그고 프로그램을 충돌 직전으로 몰고 갈 수 있다는 것입니다.

데이터를 순회하는 동안 쿼리 세트 캐시가 생성되는 것을 방지하려면 iterator() 메서드를 사용하여 데이터를 얻고 데이터를 처리한 후 삭제할 수 있습니다.

아아아아

물론 캐시 생성을 방지하기 위해 iterator() 메서드를 사용한다는 것은 동일한 쿼리 세트를 순회할 때 쿼리가 반복적으로 실행된다는 의미입니다. 따라서 iterator()를 사용할 때는 주의하고 대규모 쿼리 세트에서 작업할 때 코드가 반복적으로 쿼리를 실행하지 않는지 확인하세요

쿼리 세트가 크면 if 문이 문제입니다

앞서 언급했듯이 쿼리 세트 캐시는 if 문과 for 문을 결합하는 데 강력하며, 이는 쿼리 세트에 대한 조건부 루프를 허용합니다. 그러나 매우 큰 쿼리 세트의 경우 쿼리 세트 캐싱이 적합하지 않습니다.

가장 간단한 해결책은exists()를 iterator()와 함께 사용하여 두 개의 데이터베이스 쿼리를 사용하여 쿼리 세트 캐시 사용을 방지하는 것입니다.

아아아아

더 복잡한 해결책은 Python의 "고급 반복 방법"을 사용하여 루프를 시작하기 전에 iterator()의 첫 번째 요소를 살펴본 다음 루프할지 여부를 결정하는 것입니다.

아아아아

부적절한 최적화 방지

Queryset의 캐시는 데이터베이스에 대한 프로그램의 쿼리를 줄이는 데 사용되며, 일반적인 사용에서는 필요할 때만 데이터베이스가 쿼리되도록 합니다.

프로그램의 메모리 사용을 최적화하려면 presents() 및 iterator() 메서드를 사용하십시오. 그러나 쿼리셋 캐시를 생성하지 않기 때문에 추가적인 데이터베이스 쿼리가 발생할 수 있습니다.

따라서 코딩할 때 주의를 기울여야 합니다. 프로그램 속도가 느려지기 시작하면 코드의 병목 현상이 어디에 있는지 확인하고 도움이 될 수 있는 몇 가지 작은 최적화가 있는지 확인해야 합니다.

위 내용은 Django의 QuerySet을 효과적으로 사용하기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.