2017-11-09 5 views
0

필자가 쓰는 앱에 .exists() 쿼리가 있습니다. 나는 그것을 최적화하고 싶다. 다음과 같습니다Django`.exists()`쿼리 최적화하기

현재 ORM 발현 수율의 SQL :

SELECT DISTINCT 
    (1) AS "a", 
    "the_model"."id", 
... snip every single column on the_model 
FROM "the_model" 
WHERE (
...snip criteria... 
LIMIT 1 

이 계획 설명은 다음과 같습니다

Limit (cost=176.60..176.63 rows=1 width=223) 
    -> Unique (cost=176.60..177.40 rows=29 width=223) 
     -> Sort (cost=176.60..176.67 rows=29 width=223) 
       Sort Key: id, ...SNIP... 
       -> Index Scan using ...SNIP... on ...SNIP... (cost=0.43..175.89 rows=29 width=223) 
        Index Cond: (user_id = 6) 
        Filter: ...SNIP... 

나는 수동으로 위의 SQL을 수정하고 그래서 개별 테이블 열을 제거하는 경우 그것은 다음과 같습니다 :

SELECT DISTINCT 
    (1) AS "a", 
FROM "the_model" 
WHERE (
...snip criteria... 
LIMIT 1 

Explain plan은 어 단계들.

Limit (cost=0.43..175.89 rows=1 width=4) 
    -> Unique (cost=0.43..175.89 rows=1 width=4) 
     -> Index Scan using ...SNIP... on ...SNIP... (cost=0.43..175.89 rows=29 width=4) 
       Index Cond: (user_id = 6) 
       Filter: ...SNIP... 

여기 절약 비용은 사소한하지만 내가, 따라서 더 얕은 실행 계획을 산출 쿼리에서 DISTINCT 키워드를 제거하여 더 이상 갈 수

Limit (cost=0.43..6.48 rows=1 width=4) 
    -> Index Scan using ..SNIP... on ..SNIP... (cost=0.43..175.89 rows=29 width=4) 
     Index Cond: (user_id = 6) 
     Filter: ..SNIP... 

내가 사용하는 ORM 식을 수정할 수 있습니다 .only('id')을 누르면 한 필드 만 선택할 수 있습니다. 그러나 그 결과는 내가 원하지 않는 결과를 가져옵니다. id에서 불필요한 정렬 작업을하고 있습니다. 이상적으로는 여기에 어떤 열도 필요하지 않기 때문에 .only(None)을하고 싶습니다. 그들은 단지 무게를 추가합니다.

가능한 경우 DISTINCT 키워드를 제거하고 싶습니다. 열이 제거되면 많은 실행 시간을 추가한다고 생각하지 않습니다.

.exists()이 부울을 반환하므로 전체적으로 이렇게 할 수 있습니다. 반환 된 열은 아무 것도 사용되지 않습니다. 쿼리를 복잡하게 만들고 성능을 저하시킵니다.

+2

Django의 어떤 버전을 사용하고 있으며 해당 코드를 일으키는 코드는 무엇입니까? 'User.objects.exists()'를 시도하면'FROM "auth_user"LIMIT 1 "이'SELECT (1) AS"로 실행됩니다. – Alasdair

+0

장고 1.11.5를 사용하고 있습니다. 맞춤 코드가이를 방해하고 추가 열을 선택하게하는지 살펴 보겠습니다. –

+0

내가 모르는 곳에서 QuerySet에'.distinct()'호출이 적용되었습니다. 이것은 모든 것을 망쳐 놓고 있었다. –

답변

0

내 QuerySet 구축 중에 .distinct()이 내 .exists() 전에 호출되고있는 것으로 나타났습니다. 불필요하게 열을 선택하게되었습니다.