为什么使用 IS DISTINCT FROM - Postgres

Tia*_*tas 5 sql postgresql

这个功能的最佳用途是什么Postgres IS DISTINCT FROM,试听得到了相同的结果,COALESCE但在更短的时间内,按照测试:

SELECT COUNT(P.id)

FROM produto P
  INNER JOIN cliente CL ON P.id_cliente = CL.id_cliente

WHERE 
  COALESCE(CL.tp_pessoa,'') <> 'JURIDICA' -- test with COALESCE, average 610 ms

  (CL.tp_pessoa <> 'JURIDICA' OR CL.tp_pessoa IS NULL) -- test with OR, average 668 ms

  CL.tp_pessoa IS DISTINCT FROM 'JURIDICA' -- test with IS DISTINCT FROM, average 667 ms

  OUTRO TESTE:

  COALESCE(CL.tp_pessoa,'') <> COALESCE(P.observacao,'') -- test with IS DISTINCT FROM, average 940 ms

  CL.tp_pessoa IS DISTINCT FROM P.observacao -- test with ```IS DISTINCT FROM```, average 930 ms, a little beter here
Run Code Online (Sandbox Code Playgroud)

它的性能较低,并且是其他数据库中没有的功能,例如SQL Server,另一个不使用它的原因。

做另一个测试,两个标准都可以NULLIS DISTINCT FROM有一点优势,这就是它的用途,它更适用于哪里?

编辑:

就像@hvd说是它的一部分ANSI SQL和的结果COALESCE(CL.tp_pessoa,'') <> COALESCE(P.observacao,'')是不一样的CL.tp_pessoa IS DISTINCT FROM P.observacao

小智 12

您所看到的性能差异很小。注重正确性。

你举个例子

COALESCE(CL.tp_pessoa,'') <> COALESCE(P.observacao,'')
Run Code Online (Sandbox Code Playgroud)

相对

CL.tp_pessoa IS DISTINCT FROM P.observacao
Run Code Online (Sandbox Code Playgroud)

如果CL.tp_pessoaisNULLP.observacaois '',则第一个比较将它们视为相等,而第二个比较将它们视为不相等。

因此,如果您想将它们比较为相等,请使用第一个版本,如果您想将它们比较为不相等,请使用第二个版本。


Gor*_*off 5

第一,方便。其次,您需要对大量数据进行测试。一秒钟内,数据库服务器上可能会发生很多事情,因此百分之一秒的微小变化并不一定代表整体性能。

从积极的方面来说,我认为 Postgres 会为is distinct from. 我认为索引不一定会用于所有替代方案。

  • 在我的本地机器上对更大的银行进行了进一步测试,因此没有软件竞争,并且差异再次最小化 2230 - 2240 ms,那么性能没有问题 (2认同)

Bac*_*its 5

问题COALESCE()在于它使子句不可 SARGable。这将影响性能,因为无法使用索引。

问题在于 (CL.tp_pessoa <> 'JURIDICA' OR CL.tp_pessoa IS NULL)在于它很冗长,尤其是当您要比较两个可能都是 NULL 的字段时:

(CL.tp_pessoa <> CL2.tp_pessoa 
    OR (CL.tp_pessoa IS NOT NULL AND CL2.tp_pessoa IS NULL) 
    OR (CL.tp_pessoa IS NULL AND CL2.tp_pessoa IS NOT NULL))
Run Code Online (Sandbox Code Playgroud)

如果您正在执行 UPDATE 以将临时表与您的基表合并并且它们共享 30 个字段,并且您只想在至少一个字段不同并且 29 个非关键字段中的任何一个可以为 NULL 时进行更新。 . 你可以理解编写查询是多么痛苦。