Sql 如何简化/优化此union语句

Sql 如何简化/优化此union语句,sql,sql-server,Sql,Sql Server,我有我为客户需要的查询编写的代码。结果给了我我们所需要的,但是我得到了一些非常长的响应时间。当查询本身差异不大时,查询的第一部分比第二部分花费的时间更长。基本上,它们是两个不同的查询,我使用UNIONALL将它们合并为一个查询 任何反馈都可以简化此过程。 谢谢 这是一个相关子查询。这意味着它一行一行地运行。这是一种您应该避免使用的编程技术。将其转换为派生表。我只查看了联合的第一部分 与原始查询非常相似,只是做了一些优化程序可能会自己做的小简化 使用我编写的测试数据生成相同的结果。请随意用更具代表

我有我为客户需要的查询编写的代码。结果给了我我们所需要的,但是我得到了一些非常长的响应时间。当查询本身差异不大时,查询的第一部分比第二部分花费的时间更长。基本上,它们是两个不同的查询,我使用UNIONALL将它们合并为一个查询

任何反馈都可以简化此过程。 谢谢


这是一个相关子查询。这意味着它一行一行地运行。这是一种您应该避免使用的编程技术。将其转换为派生表。

我只查看了联合的第一部分

与原始查询非常相似,只是做了一些优化程序可能会自己做的小简化

使用我编写的测试数据生成相同的结果。请随意用更具代表性的东西来扩展它。它使用下面复制的CTE

-- CTE Version
With T As (
Select
  l.Storage_Loc_Nbr,
  l.MMM_Id_Nbr,
  Count(Load_ID) As LoadCount
From 
  t_load l
Where
  l.QC_Status_Code like 'R%' And
  l.mmm_Facility_Code ='MC' And
  l.Active_Status_Ind='A' And
  l.MMM_Id_Nbr between '702004%' and '702011%'
Group By
  l.Storage_Loc_Nbr,
  l.MMM_Id_Nbr
)

Select
  t1.Storage_Loc_Nbr LocNbr,
  t1.LoadCount CurrentLoadCount,
  t1.MMM_Id_Nbr,
  t2.TotalCount - t1.LoadCount OtherLocCount
From
  T t1
    Inner Join (
      Select
        MMM_Id_Nbr,
        Sum(LoadCount) TotalCount
      From
        T  
      Group By
        MMM_Id_Nbr
    ) t2
    On t1.MMM_Id_Nbr = t2.MMM_Id_Nbr
    Left Outer Join
  t_Storage_Location sl
    On t1.Storage_Loc_Nbr = sl.Storage_Loc_Nbr
Where
  sl.Storage_Loc_Type_Code = 'CD' and
  t1.LoadCount <= 1 And
  t2.TotalCount - t1.LoadCount > 0
是另一个使用窗口功能和免费CTE的版本:

-- Window Function Version
With T As (
Select
  l.MMM_Id_Nbr,
  l.Storage_Loc_Nbr,
  Count(Load_ID) Over (Partition By MMM_ID_Nbr, Storage_Loc_Nbr) As LoadCount,
  Count(Load_ID) Over (Partition By MMM_ID_Nbr) As TotalCount
From 
  t_load l
Where
  QC_Status_Code like 'R%' And
  mmm_Facility_Code ='MC' And
  Active_Status_Ind='A' And
  l.MMM_Id_Nbr between '702004%' and '702011%'
)

Select
  t1.Storage_Loc_Nbr LocNbr,
  t1.LoadCount CurrentLoadCount,
  t1.MMM_Id_Nbr,
  t1.TotalCount - t1.LoadCount OtherLocCount
From
  T t1
    Left Outer Join
  t_Storage_Location sl
    On t1.Storage_Loc_Nbr = sl.Storage_Loc_Nbr
Where
  sl.Storage_Loc_Type_Code = 'CD' and
  t1.LoadCount <= 1 And
  t1.TotalCount - t1.LoadCount > 0

我无法在生产环境中生成派生表..:当然可以。它是查询的一部分,不是一个真正的表。请用谷歌搜索派生表。你能写一些例子来说明如何根据我的查询创建CTE或派生表吗?你看过执行计划了吗?看看瓶颈在哪里?使用以通配符开头的类似模式可以防止索引访问,但仍然可以从索引中获益。索引的完整扫描可能比表扫描快得多。有索引吗?@HABO+1。OP您是否尝试过使用SQL探查器?
-- CTE Version
With T As (
Select
  l.Storage_Loc_Nbr,
  l.MMM_Id_Nbr,
  Count(Load_ID) As LoadCount
From 
  t_load l
Where
  l.QC_Status_Code like 'R%' And
  l.mmm_Facility_Code ='MC' And
  l.Active_Status_Ind='A' And
  l.MMM_Id_Nbr between '702004%' and '702011%'
Group By
  l.Storage_Loc_Nbr,
  l.MMM_Id_Nbr
)

Select
  t1.Storage_Loc_Nbr LocNbr,
  t1.LoadCount CurrentLoadCount,
  t1.MMM_Id_Nbr,
  t2.TotalCount - t1.LoadCount OtherLocCount
From
  T t1
    Inner Join (
      Select
        MMM_Id_Nbr,
        Sum(LoadCount) TotalCount
      From
        T  
      Group By
        MMM_Id_Nbr
    ) t2
    On t1.MMM_Id_Nbr = t2.MMM_Id_Nbr
    Left Outer Join
  t_Storage_Location sl
    On t1.Storage_Loc_Nbr = sl.Storage_Loc_Nbr
Where
  sl.Storage_Loc_Type_Code = 'CD' and
  t1.LoadCount <= 1 And
  t2.TotalCount - t1.LoadCount > 0
-- Window Function Version
With T As (
Select
  l.MMM_Id_Nbr,
  l.Storage_Loc_Nbr,
  Count(Load_ID) Over (Partition By MMM_ID_Nbr, Storage_Loc_Nbr) As LoadCount,
  Count(Load_ID) Over (Partition By MMM_ID_Nbr) As TotalCount
From 
  t_load l
Where
  QC_Status_Code like 'R%' And
  mmm_Facility_Code ='MC' And
  Active_Status_Ind='A' And
  l.MMM_Id_Nbr between '702004%' and '702011%'
)

Select
  t1.Storage_Loc_Nbr LocNbr,
  t1.LoadCount CurrentLoadCount,
  t1.MMM_Id_Nbr,
  t1.TotalCount - t1.LoadCount OtherLocCount
From
  T t1
    Left Outer Join
  t_Storage_Location sl
    On t1.Storage_Loc_Nbr = sl.Storage_Loc_Nbr
Where
  sl.Storage_Loc_Type_Code = 'CD' and
  t1.LoadCount <= 1 And
  t1.TotalCount - t1.LoadCount > 0