Django ORM 3가지 특징

Nicholas·2022년 10월 5일
0

Django

목록 보기
14/14

1. LazyLoading(지연로딩)

- 데이터가 필요한 시점에 SQL문을 호출하는 특징

  • ORM만 정의한다고해서 실행되는것이아닌 QuerySet이 평가될때 DB에 SQL문을 날려 통신한다.

    • QuerySet이 평가될때란?
      파이썬의 generator라 생각하면 쉽다.

      user = User.objects.filter(age='20') # 이 시점에는 SQL문을 호출하지않는다.
      
      print(user) # QuerySet이 평가될때 SQL문으로 DB에서 데이터를 호출한다.
    • 문제점

      1. 같은 값을 가져오는데도 요청할때마다 호출한다.
        user = User.objects.filter(age='20')
        
        print(user[0])   
        print(user[1])
        # 두번 SQL Query가 호출된다
      2. 이미 호출한 데이터를 다시한번 호출할 수도 있다.(N+1 Problem)
        # category의 table에 id, name 있고
        # product table는 id, name, category_id가 있다.
        
        products = product.objects.filter(category_id = 1)
        
        result = [{
        		"category_id   : product.category.id,
            "category_name : product.category.name,
        		"id"           : product.id,
        		"name"         : product.name} for product in products]

2. Caching

각 QuerySet는 DB접근을 최소화하기위해 한번 접근한 데이터를 가지고있는데 특징

  1. QuerySet를 index, slice로 접근하면 cach가 되지않는다.
    user = User.objects.filter(id = 1)
    
    print(user[0])  # LIMIT 1이 포함된 SELECT문 호출 
    print(list(user)) # id가 1인 SELECT 문이 호출
    # 두번 SQL Query가 호출된다
    다만, QuerySet를 호출한뒤에 index, slice로 접근하면 cach를 사용할수있다.
    user = User.objects.filter(id = 1)
    
    print(list(user)) # id가 1인 SELECT 문이 호출
    print(user[0])  # print(list(user))에서의 SQL문 호출의 caching된 데이터 사용
    # 한번 SQL Query가 호출된다

3. EagerLoading(즉시로딩)

  • 1:1관계, 1:다 관계, 다:다 관계일때 for문이 실행될때 외래키 관계인데이터를 가지고오지않고 해당 모델의 데이터를 가져온다 그리고 그 해당모델에서 외래키관계에 있는 데이터를 다시 호출해. 데이터를 가져온다. 참조한 데이터가 10개면 상관없는데 수십만개라면 한번의 for문을 돌때마다 그에 참조된 수십만개의 데이터를 일일이 Query문을 날려서 처리해야한다. 이를 N+1 Problem이라 한다.
    • N+1 Problem : 1개의 메인Query와 0~N개의 서브 Query 구성에서 발생하는 문제
  • 해결법 : 필요한 정보를 미리 모두 메모리에 가져온다. 즉 LazyLoading처럼 데이터가 필요할때 SQL문으로 일일이 호출하는 것이 아니라 처음 SQL문으로 데이터를 가져올때 참조된 데이터 모두다 즉시 가져와 메모리에 Caching한다.
  • EagerLoading를 하는 방법은 두가지
    • select_related : SQL Query문 JOIN을 통해 데이터를 즉시가져오는 방법
      • 1:1 관계, 1:N 관계에서 N쪽에, 정참조관계일때 사용될수있다
    • prepatch_related : 추가 쿼리를 통해 데이터를 즉시가져오는방법
      • 1:다 관계에서 1쪽에, 역참조관계일때 사용될수 있다.
profile
WEB Developer

0개의 댓글