优化同一个表中的多个选择

时间:2013-06-26 22:32:09

标签: sql sql-server sql-server-2008-r2

我想优化报告使用的查询。不幸的是,我无法修改报告,因此我必须提供特定格式的数据集。

所以,假设我有一个看起来像这样的表(实际上,它有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,但我没有获得任何性能提升。

1 个答案:

答案 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)
;

See a Live Demo at SQL Fiddle

请注意,您不需要临时表 - 您可以执行15个连接,然后在CROSS APPLY中只需参考每个列来自的表。

这提出了一个观点。您的数据来自15个表格!如果任何Type值组都来自不同的表子集,那么这可能不是最好的方法!例如,假设MiscColumn1MiscColumn2来自2个没有在另一个组中表示的列的表。在这种情况下,从主查询中删除这两个表会好得多,而UNION ALL SELECT只是这两个表中的两列。

我说这是基于我可能会错误的印象,你的报告平台将自己加入各种相关数据。如果是这样,那么你不应该尝试将所有数据的统一视图放在一起,然后再将其重新打破 - 这无助于在系统上进行额外的工作。上述查询中对DISTINCT的需求突出显示了实现所需的精简结果集所需的额外内存,I / O和CPU。如果有办法解决这个问题,我认为你应该这样做。