使用CASE的效率当... ISNULL/COALESCE不是空的

pyo*_*yon 6 sql-server

请考虑以下情形:

  • 有三种类型的实体,说Foo,BarBaz.
  • 每个Foo必须与a Bar或a 相关联Baz,但不能同时与两者相关联.

该方案已按以下方式实施:

  • 有三个表:Foo,BarBaz.
  • Foo有两个外键领域:Bar_IDBaz_ID.
  • 正是其中一个外键领域必须是NULL.

现在我想建立一个查询显示的列表FooS,其中包括的说明BarBaz每个Foo关联到.实际上,a的描述BarBar表中相应行的字段的非常复杂的公式.这同样适用于Baz.

我当前的查询如下所示:

SELECT    Foo.*,
          CASE
            WHEN Foo.Bar_ID IS NOT NULL THEN
              -- a formula, say...
              ISNULL(Bar.LotNumber + '-', '') + Bar.ItemNumber
            WHEN Foo.Baz_ID IS NOT NULL THEN
              -- another formula, say...
              ISNULL(Baz.Color + ' ', '') + Baz.Type
          END AS 'Ba?Description'
FROM      Foo
LEFT JOIN Bar ON Bar.Bar_ID = Foo.Bar_ID
LEFT JOIN Baz ON Baz.Baz_ID = Foo.Baz_ID
Run Code Online (Sandbox Code Playgroud)

前面的查询是否比...更多,更少或同等效率

SELECT    Foo.*,
          ISNULL( -- or COALESCE
            ISNULL(Bar.LotNumber + '-', '') + Bar.ItemNumber,
            ISNULL(Baz.Color     + ' ', '') + Baz.Type
          ) AS 'Ba?Description'
FROM      Foo
LEFT JOIN Bar ON Bar.Bar_ID = Foo.Bar_ID
LEFT JOIN Baz ON Baz.Baz_ID = Foo.Baz_ID
Run Code Online (Sandbox Code Playgroud)

...?

gbn*_*gbn 5

从理论上讲,CASE应该是因为只评估了一个表达式.几个链式ISNULL都需要处理.

但是,您需要有一个大的(10000行)数据集来注意任何差异:大多数处理进入实际的表访问,JOIN等.

你试过吗?您可以使用SQL事件探查器查看每个查询的CPU等.