[Django]장고 ORM과 쿼리셋(QuerySets) 속도 높이는 가장 쉬운 방법

2022. 2. 10. 12:45python 전문가로/Django

반응형

안녕하세요.

장고에서 데이터베이스로 쿼리셋을 날려서 데이터를 가져올때 ORM 언어를 써서 사용합니다.

 ORM이란 Object-Relational Mapping의 약자로 객체(Object)와 관계형 데이터베이스(Relational Database)의 데이터를 매핑(Mapping)해주는 것을 의미합니다. 객체 간의 관계를 바탕으로 SQL을 자동 생성하여 sql쿼리문 없이도 데이터베이스의 데이터를 다룰 수 있게 해주는 언어입니다.

예를들어서, views.py에서 아래와 같게 말이죠.

from blog.models import *

def index(request):
    ww_equity = wm_web.objects.filter(base_ymd=date, asset='equity')
    equity_china_decoded = ww_equity.filter( country='China', knd= 'decoded').values()
    equity_china_decoded_json = json.dumps(list(equity_china_decoded), cls=DjangoJSONEncoder)
    
    context = {
        'equity_china_decoded_json': equity_china_decoded_json
        }
        
    return render(
        request, 'blog/index.html', context
    )

 

ORM은 쿼리문보다 훨신 직관적이고 간략합니다(가독성이 높음). 하지만, ORM의 단점 중 하나는 많이 쓸수록, 조금만 복잡해질수록 속도가 저하된다는 것입니다.

저는 무려 아래와 같이 차트 16개의 데이터(16번 쿼리를 날리는것과 동일한 셈이죠...)를 가져오는데 약 30초가 걸렸습니다.(이 속도를 확인할때에는 f12를 눌러 '네트워크'탭에서 확인해볼 수 있습니다.) 

 

그래서 이건 말이 안된다고 생각해서 여러방법으로 서칭을 해보았는데,

바로 list()로 캐싱을 해서 인덱스로 데이터를 추출하는 것이 더 DB접근을 최소화 할 수 있다는 검색 결과가 많았습니다. 

예를들어 아래와 같이 말이죠.

from blog.models import *

ww_equity = wm_web.objects.all()
list(ww_equity)
ww_equity[0]
ww_equity[1]

 

하지만, 저는 저의 데이터베이스 특성상 인덱스를 사용할 수 없었고, 조건식으로 데이터를 추출하기 때문에 위와 같은 방식은 필요가 없었습니다. 

 그래서 이것저것 시도해본 결과를 여러분들께 공유드리고자 합니다.(주관적인 내용입니다.)

바로, "데이터프레임"화 입니다! 

예를들어, 아래와 같습니다. 

from blog.models import *

def index(request):
    wm_decoded = list(wm_web.objects.filter(base_ymd=date, knd='decoded').values())
    df_wm_decoded = pd.DataFrame(wm_decoded)
    equity_china_decoded = df_wm_decoded[(df_wm_decoded['asset']=='equity') & (df_wm_decoded['country']=='China')]
    equity_china_decoded_json = equity_china_decoded.to_json(orient="records")
    
    context = {
        'equity_china_decoded_json': equity_china_decoded_json
        }
     
    return render(
        request, 'blog/index.html', context
    )

먼저, ORM결과를 list()화 하고 DataFrame화 하였습니다.

결과는??

30초가 2초대로 ㅠㅠㅠ...

엄청난 발전이네요!!

여러분도 시간이 너무 오래걸리시다면 Django의 ORM 튜닝을 권장드립니다!

 

그럼 오늘도 좋은하루 되세요 :)