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
它具有较低的性能,并且是SQL Server
等其他数据库中找不到的功能,这是不使用它的另一个原因。
进行另一项测试,其中两个条件都可以NULL
,IS DISTINCT FROM
略有优势,这将是它的用途,还有更多适用的标准?
编辑:
就像@hvd所说的那样,它是ANSI SQL
的一部分,COALESCE(CL.tp_pessoa,'') <> COALESCE(P.observacao,'')
的结果与CL.tp_pessoa IS DISTINCT FROM P.observacao
的结果不同。
答案 0 :(得分:4)
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))
如果您正在进行UPDATE以将临时表与基表合并,并且它们共享30个字段,并且您只想在至少有一个字段不同时更新,并且29个非关键字段中的任何一个都可以NULL ...你可以理解编写查询会有多痛苦。
答案 1 :(得分:2)
首先,很方便。其次,您需要对大量数据运行测试。在一秒钟内,数据库服务器上可能会发生很多事情,因此百分之一秒的小变化不一定表示整体性能。
从积极的方面来说,我认为Postgres会使用is distinct from
的索引。我不认为索引必然会用于所有替代方案。
答案 2 :(得分:2)
您看到的性能差异很小。注重正确性。
你举个例子
COALESCE(CL.tp_pessoa,'') <> COALESCE(P.observacao,'')
与
CL.tp_pessoa IS DISTINCT FROM P.observacao
如果CL.tp_pessoa
为NULL
,而P.observacao
为''
,则第一次比较将它们视为相等,而第二次比较将它们视为不相等。
因此,如果要将它们相等,请使用第一个版本;如果要将它们比较为不相等,则使用第二个版本。
答案 3 :(得分:1)
如果column1
上有一个索引,如CREATE INDEX "index_name" ON table1 USING btree (column1);
,那么在IS DISTINCT FROM
sql引擎的情况下,可以使用该索引。使用COALESCE
时,它不能。