아오 멍청하게짜서… 너무 느리게 돌아가네요… 도와주세요… ㅠㅠ 목표: 적당히

 
Han Cold Kim

아오 멍청하게짜서… 너무 느리게 돌아가네요… 도와주세요… ㅠㅠ

목표: 적당히 안느리면서, 최소한의 소스수정이 이뤄져야함…

일단 약간의 상황을 말씀드리면 어떤분께서 잠시동안 자리를 비우셔야해서 그분이 진행중인걸 제가 해야하는 상황입니다. 그래서 최소한으로 수정하면서 최대의 효과(?)를 누리고 싶거든요…

일단 간단한 검색기능입니다…

Post모델과 Comment모델이 있는데,

두 모델 모두 content라는 필드를 가지고있고,

추가로 Comment모델은 Foreign Key로 Post를 가지고 있습니다…

일단 지금은 검색기능이 없습니다.

Post의 content나 Comment의 content에 예를들어 ‘장고’가 포함되어 있는것만 출력해주도록 해야할 껀데

Views.py에서 템플릿으로 넘기는건 Post 쿼리셋만 넘기고,

템플릿에서 post.comment_set.all로 post에 붙은 comment를 전부 출력해주는 방식으로 짜져 있더라고요.

그래서 뷰는 안건드리고 post만 검색 붙여서 넘겨야겠다는 생각으로 이것저것 했는데…

가져오는 개수가 많아질 수록… (당연하지만…) 엄청 느리네요…

위 소스 2행이 엄청 느리거든요…

템플릿 수정없이 개선할 방법 있을까요…?

  • Han Cold Kim

    와… ㄷㄷ 원강희님이 알려주신 방법대로 하니까 엄청 빨라졌네요… 감사합니다.

    Han Cold Kim

    values_list를 사용하면 id를 가져오기 위해서 filter에 걸린 개수만큼 select를 날리는게 아닌가보죠…??

    김슬

    제가 보기엔 느린 부분은 pk를 가져오는 부분보다는 LIKE쿼리를 날리는 부분 자체일것 같은데요. (지금 코드상으론 같은 줄이긴 할테지만) 일단 프로파일링 먼저 해보시길 추천드리구요.

    LIKE쿼리는 구조상 느릴 수 밖에 없고 빠른 성능을 원하시면 역색인을 아마 하셔야 할 텐데..

    급하다면 일단 limit부터 걸고 봅시다.

    Han Cold Kim

    일단 프로파일링과 역색인을 먼저 알아보고 와야겠네요… ㅠㅠ 감사합니다!

    김슬

    역색인쪽은 sphinx, lucene, whoosh 같은 라이브러리를 사용하시면 될 거구요. 한국어 아날라이저를 달 수 있다면 좋겠지만 너무 복잡해지는 문제도 있고.. ngram을 테스트 해보시고 품질을 보고 결정하시면 될 듯 합니다.
    프로파일링은.. 우선은 django debug toolbar에서 보는 정도로도 되지 않을까요

    Jung Kyoung Up

    from django.db.models import Q

    query = request.GET[‘q’]
    q = Q(comment__content__contains=query) | Q(content__contains=query)
    q = q & Q(board_id=board.id)
    Post.objects.filter(q).order_by(‘-created_at’)

    확인은 안해봤지만 이런식으로 쿼리 날리는게 될겁니다. 쿼리가 어떻게 뜨는지 보고 적절히 select_related 같은거 넣어줘야할 수도 있겠네요.

    박영록

    윗분의 코드처럼 하면 한 방 쿼리로 가능해져서 id 리스트를 in 조건으로 넘긴다거나, 세 번 쿼리를 날리는 비효율은 제거할 수 있습니다. 다만 DB에 따라 OR 조건이 비정상적으로 느린 경우가 있으니 그것만 조심하시면 윗분의 코드가 정답이죠.

    물론 본격적인 검색 기능이 필요하다면 검색 엔진을 넣는 것이 좋겠구요.

Advertisements