我想优化报告使用的查询。不幸的是,我无法修改报告,因此我必须提供特定格式的数据集。
所以,假设我有一个看起来像这样的表(实际上,它有25列和20k行):
Name Description Price MiscColumn1 MiscColumn2
Tea test description 10 misc1 misc2
Coffee test desc 20 misc3 misc4
Water test 20 misc1 misc2
所以,我需要将此数据集转换为如下所示:
Type Name Description Price MiscColumn1 MiscColumn2
1 Tea test description NULL NULL NULL
1 Coffee test desc NULL NULL NULL
1 Water test NULL NULL NULL
2 NULL NULL 10 NULL NULL
2 NULL NULL 20 NULL NULL
3 NULL NULL NULL misc1 misc2
3 NULL NULL NULL misc3 misc4
所以,基本上我需要做的是选择3组不同的记录回到数据集中。
我目前所做的是:
Create #tempTable
然后执行3个单独的不同选择:
insert into #tempTable (Name, Description)
select distinct Name, DEscription from myTable
insert into #tempTable (Price)
select distinct Price from myTable
但它真的很慢,我的数据可能需要5秒钟才能完成。
另外,我试图使用UNION,但我没有获得任何性能提升。
答案 0 :(得分:4)
您可以在一个语句中执行此操作,该语句应包含单个扫描,如下所示:
SELECT DISTINCT
X.*
FROM
dbo.MyTable T
CROSS APPLY (VALUES
(1, T.Name, T.Description, NULL, NULL, NULL),
(2, NULL, NULL, T.Price, NULL, NULL),
(3, NULL, NULL, NULL, T.MiscColumn1, T.MiscColumn2)
) X (Type, Name, Description, Price, MiscColumn1, MiscColumn2)
;
请注意,您不需要临时表 - 您可以执行15个连接,然后在CROSS APPLY
中只需参考每个列来自的表。
这提出了一个观点。您的数据来自15个表格!如果任何Type
值组都来自不同的表子集,那么这可能不是最好的方法!例如,假设MiscColumn1
和MiscColumn2
来自2个没有在另一个组中表示的列的表。在这种情况下,从主查询中删除这两个表会好得多,而UNION ALL SELECT
只是这两个表中的两列。
我说这是基于我可能会错误的印象,你的报告平台将自己加入各种相关数据。如果是这样,那么你不应该尝试将所有数据的统一视图放在一起,然后再将其重新打破 - 这无助于在系统上进行额外的工作。上述查询中对DISTINCT
的需求突出显示了实现所需的精简结果集所需的额外内存,I / O和CPU。如果有办法解决这个问题,我认为你应该这样做。