В чем разница между "x IS NULL" и "NOT (x IS NOT NULL)"? - PullRequest
4 голосов
/ 23 декабря 2011

Есть ли существенная разница в исполнении, производительности или логике postgresql между

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

и

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

Очевидно, что если написать от руки, первое выражение будет тем, которое я напишу (кто намеренно написал бы двойной отрицательный знак ?!). Но в этом случае я использую библиотеку rul's arel для динамического создания обеих версий, примерно так:

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_clause будет arel_table[:deleted_at].not_eq(nil), но для других search_terms это может быть множество предложений, включая составные предложения и подвыборы. Добавляя .not в конец, arel всегда будет генерировать SQL второй формы. Я мог бы сгенерировать первую форму, создав специальный чек для моих NULL чеков и вручную сгенерировав .eq или .not_eq, в зависимости от обстоятельств, но я бы хотел получить определенную выгоду, прежде чем сделать мой код более многословен.

1 Ответ

7 голосов
/ 23 декабря 2011

Используйте EXPLAIN , чтобы увидеть разницу, если она есть.

Я думаю, оптимизатор запросов оптимизирует это, но я не проверял исходный код для этого примера.

Редактировать: я был не прав, это не оптимизировано вообще. Где ("users". "Dele_at" IS NULL) может использовать индекс, условие (NOT ("users". "Dele_at" IS NOT NULL)) приводит к последовательному сканирование диска.

...