1

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

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

4

1 回答 1

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

在 SQL Fiddle 上查看现场演示

请注意,您不需要临时表——您可以进行 15 次连接,然后CROSS APPLY简单地引用每列来自的表。

这就提出了一个观点。您的数据来自 15 个表!如果任何Type值分组来自不同的表子集,那么这可能不是最好的方法!例如,假设它MiscColumn1来自MiscColumn22 个在另一个组中没有表示列的表。在这种情况下,最好从主查询中删除这 2 个表,并UNION ALL SELECT分别从这些表中删除 2 列。

我这么说是基于我得到的可能错误的印象,即您的报告平台将自己加入各种相关数据。如果是这样,那么您不应该尝试将所有数据的统一视图放在一起,然后再次将其分解——那是无缘无故地在系统上增加额外的工作。对DISTINCT上述查询的需求突出显示了实现所需的精简结果集所需的额外内存、I/O 和 CPU。如果有任何方法可以解决这个问题,我认为你应该这样做。

于 2013-06-26T23:18:20.907 回答