Skip to content

Latest commit

 

History

History
101 lines (69 loc) · 5.56 KB

26.md

File metadata and controls

101 lines (69 loc) · 5.56 KB

26. Finding and Reducing Bottlenecks

26.1 Should You Even Care?

명심해야 할 점은 이른 최적화는 좋지 않다는 것이다. 아직 사이트의 규모가 크지않고 잘 로딩되고 있다면, 이 챕터는 넘어가도 좋다.

26.2 Speed Up Query-Heavy Pages

너무 많고 충분히 원활하지 않은 쿼리들로 인한 병목 현상을 어떻게 줄이는지 알아보자.

추가로 Django 공식 문서에서 데이터베이스 액세스 최적화에 대해 읽어 보길 바란다.

참조: https://docs.djangoproject.com/en/3.2/topics/db/optimization/

26.2.1 Find Excessive Queries With Django Debug Toolbar

django-debug-toolbar를 사용하면 대부분의 쿼리가 발생하는 곳을 확인하는데 도움이 된다. 다음과 같은 병목 현상을 찾을 수 있을 것이다.

  • 한 페이지 내에서 중복되는 쿼리
  • 예상보다 더 많은 쿼리를 호출하는 ORM 호출
  • Slow queries

아마 최적화가 필요한 URL이 대략적으로 떠오를 것이다. 딱 봐도 로딩이 느린 페이지 라던가..

아직 django-debug-toolbar가 없다면 로컬에 설치하라. 웹 브라우저에서 프로젝트를 보고 SQL 패널을 확장하고, 현재 페이지에 포함된 쿼리 수를 확인할 수 있다.

26.2.2 Reduce the Number of Queries

  • ORM의 select_related() 함수를 활용하여 query들을 combine하기.
  • select_related()를 사용할 수 없는 상태의 many-to-many, many-to-one 관계의 경우 prefetch_related()를 사용해보기.
  • 동일한 쿼리가 템플릿당 두 번 이상 생성되는 경우 쿼리를 Python 보기로 이동하고 컨텍스트에 변수로 추가한 다음 템플릿 ORM 호출이 이 새 컨텍스트 변수를 가리키도록 하기.
  • Memcached 또는 Redis와 같은 키/값 저장소를 사용하여 캐싱을 구현하고, 뷰에서 실행되는 쿼리 수를 확인하는 테스트를 작성한다.
  • django.utils.function.cached_property 데코레이터를 사용하여 객체 인스턴스의 수명 동안 메서드 호출 결과를 메모리에 캐시해보기.

26.2.3 Speed Up Common Queries

  • 인덱스가 가장 일반적이고 느린 쿼리 속도를 높이는 데 도움이 되는지 확인하라. 해당 쿼리에 의해 생성된 원시 SQL을 살펴보고 가장 자주 필터링/정렬하는 필드에 대해 인덱싱을 하고, 생성된 WHERE 및 ORDER_BY 절을 살펴보라.
  • 인덱스가 실제로 프로덕션에서 수행하는 작업을 이해하라. 개발 시스템은 프로덕션에서 발생하는 일을 완벽하게 복제할 수 없으므로 데이터베이스에서 실제로 발생하는 일을 분석하고 이해하는 방법을 배워야 한다.
  • Common query의 쿼리 플랜을 살펴보라.
  • 데이터베이스의 slow query 로깅 기능을 켜고 slow query가 자주 발생하는지 확인하라.
  • 개발 중에 django-debug-toolbar를 사용하여 프로덕션에 들어가기 전에 잠재적으로 느린 쿼리를 방어적으로 식별하라.

좋은 인덱스가 있고 어떤 쿼리를 다시 작성해야 할지 알 수 있을 만큼 충분한 분석을 수행한 후에는 쿼리를 다시 작성하는 방법에 대한 몇 가지 시작 팁을 알아보자.

  1. 가능하면 더 작은 결과 집합을 반환하도록 로직을 다시 작성하라.
  2. 인덱스가 보다 효과적으로 작동할 수 있도록 데이터를 다시 모델링하라.
  3. ORM으로 생성된 쿼리보다 더 효율적으로 작동할 수 있는 곳에 원시 SQL로 작성하라.

Note

TIP: 분석 팁

MySQL의 EXPLAIN command 활용하기

django-debug-toolbar의 SQL panel에서도 EXPLAIN 기능을 사용할 수 있다.

26.2.4 Switch ATOMIC_REQUESTS to False

26.3 Get the Most Out of Your Database

26.3.1 Know What Doesn’t Belong in the Database

대형 사이트의 관계형 데이터베이스에 절대 들어가지 말아야 할 두 가지

  1. Logs
  2. Ephemeral data (임시 데이터) : 지속적으로 다시 작성해야 하는 데이터는 관계형 데이터베이스에서 사용하기에 적합하지 않다. 대신 이 데이터를 Memcached, Redis 및 기타 비관계형 저장소로 이동하라.
  3. binary data

26.3.2 Getting the Most Out of PostgreSQL

26.3.3 Getting the Most Out of MySQL

26.4 Cache Queries With Memcached or Redis

참조

26.5 Identify Specific Places to Cache

고려할 사항

  • 가장 많은 쿼리가 포함된 보기/템플릿은 무엇인가?
  • 가장 많이 요청되는 URL은 무엇인가?
  • 페이지의 캐시는 언제 무효화되어야 하는가?

26.6 Consider Third-Party Caching Packages

Third-Party Caching Package가 제공하는 기능

  • QuerySet 캐싱.
  • 캐시 무효화 설정/메커니즘.
  • 다양한 캐싱 백엔드.
  • 캐싱에 대한 대체 또는 실험적 접근 방식.

주로 쓰이는 caching package

  • django-cacheops
  • django-cachalot

26.7 Compression and Minification of HTML, CSS, and JavaScript

26.8 Use Upstream Caching or a Content Delivery Network