昨天我问了一个问题,其中一个答案让我思考性能。
继续,我有一个表示亲子关系的表:
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对性能的影响更大。
尝试以下两个查询
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%
我无法断言大量数据的查询成本。它可能会改变。用你自己的数据试试。