2011-12-23 3 views
4

"x IS NULL"과 "NOT (x IS NOT NULL)"의 차이점은 무엇입니까? 손으로 쓴 경우

SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) 

과 분명히

SELECT "users".* FROM "users" WHERE (NOT ("users"."deleted_at" IS NOT NULL)) 

사이에 상당한 PostgreSQL을의 실행 성능의 차이, 또는 논리가되고, 첫 번째 표현은 내가 쓰는 것 하나 (누구 것 의도적으로 이중 부정을 쓰는가?!).

def generate_query(search_terms, negated=false, users=User) 
    where_clause = arel_for_one_of_many_possible_queries(search_terms) 
    where_clause = where_clause.not if negated 
    users.where(where_clause) 
end 

을 그리고, "deleted" SEARCH_TERM를 들어, where_clausearel_table[:deleted_at].not_eq(nil)을 수 있지만 다른 SEARCH_TERMS 것이 될 수있다 :하지만이 경우에는, 나는 일종의과 같이 동적으로 두 버전을 만들 루비의 arel 라이브러리를 사용하고 있습니다 복합 조항과 하위 선택을 포함한 다양한 절. .not을 끝에 추가하면 arel은 항상 두 번째 형식의 SQL을 생성합니다. I 은 내 NULL 검사를 특수 케이스로하여 첫 번째 양식을 생성하고 수동으로 .eq 또는 .not_eq을 생성 할 수 있지만 코드를 자세히 작성하기 전에이를 수행하는 것이 확실합니다.

+1

두 개의 WHERE 절이 완전히 동일한 결과를 산출합니다. 기능적 차이는 없습니다. 그러나 쿼리 플래너는 식에 다른 피팅 인덱스를 사용할 수 없을 것입니다. –

답변

7

차이가있을 경우 EXPLAIN을 사용하십시오.

나는이 쿼리 리터 러가 이것을 최적화 할 것이라고 생각하지만이 예제의 소스 코드를 확인하지는 않았다.

편집 : 나쁘다. 전혀 최적화되지 않았다. 인덱스의 사용할 수있다 ("사용자". "deleted_at가"NULL이다) 여기서 순차적 디스크 스캔 조건 결과 ("deleted_at"NOT ("사용자". NULL) 없음).

+0

죄송합니다. 분명히'explain'을 체크해야합니다! 감사. 그러나, 일을 절대적으로 명확하게하기 위해, 두 논리적 인 차이는 없습니다. 맞습니까? 나는 때때로 정확한 SQL 관계형 대수 규칙이 몇 가지 불행한 놀라움으로 이어질 수 NULL 평등을 처리하기 위해 무엇을 잊어 버려. –

+0

FWIW, PostgreSQL의 8.4.9의 쿼리 라이터 나를 위해이를 재 작성하지 않는 것. 그래서 나는 그것이 상당한 성능 차이가 있는지 확인하기 위해 생산 데이터를 테스트해야합니다. –

+0

두 쿼리 계획의 차이점을 보여 주실 수 있습니까? –