UNION与CROSS应用性能



昨天我问了一个问题,其中一个答案让我思考性能。

继续,我有一个表示亲子关系的表:

PARENT | CHILD
   1   |   2
   1   |   3
   2   |   4

两个字段都是代表一个人的数字。

我需要取这个表中不同的人的组,而不是导入child或parent。我首先想到的查询是最明显的:

 SELECT DISTINCT PARENT FROM TABLE1
 UNION SELECT DISTINCT CHILD FROM TABLE1

但下面这个似乎表现得更好(至少在我的实际数据中):

 SELECT DISTINCT CASE WHEN N.n=1 THEN parent ELSE child END 
 FROM TABLE1
 CROSS APPLY(SELECT 1 UNION SELECT 2)N(n)

我的问题是

  • 这第二个查询真的比我建立的第一个总是快吗?
  • 只是好奇,有没有更快的方法?

第一个查询比第二个查询具有较高的IO开销和较低的CPU开销。第二个查询比第一个查询有低IO和更多的CPU。

我建议使用第二个查询,因为IO比CPU对性能的影响更大。

如果你可以减少你的查询的IO和增加CPU成本是更好的减少CPU成本和增加IO成本

尝试以下两个查询

SELECT PARENT FROM TABLE1
UNION SELECT CHILD FROM Table1

UNION将为您区分。在子查询中不需要使用DISTINCT。这样,您可以将DISTINCT SORT操作符从2减少到1。它还消除了合并两个子查询的需要。

SELECT DISTINCT Id
FROM 
(
   SELECT PARENT, CHILD
   FROM TABLE1
) AS S
UNPIVOT
(
   Id FOR AccountType IN ([Parent], [Child])
) AS UP

它也扫描table一次,但不引入任何新的常量。

这是我的机器的查询成本与样本数据

  • 有问题的查询1:40%
  • 问题中的Query2: 23%
  • 我的回答中的Query1: 20%
  • 我的回答中的Query2: 17%

我无法断言大量数据的查询成本。它可能会改变。用你自己的数据试试。

最新更新