SQL查询优化合并表

时间:2018-02-07 09:48:49

标签: sql sql-server tsql optimization

问题:我的一个问题很慢,我无法理解它。

上下文:我创建了以下数据库。我们想要组合所有这些表,它们根本没有相同的列。所以没有联盟,我们不想丢失任何数据,因为我们想要了解我们需要“清理”的内容,因此我们使用完全连接来创建合并表。

数据库概述

  1. 昏暗数据

    • 合并(下面列的内连接)
    • 用户
    • 角色
    • 权利
  2. Peach数据库

    • 合并
    • 用户
    • 作用
    • 合同(此表有一个我们以后需要的objID)
  3. CICS

    • 合并用户
  4. HR

    • Zuordnung
    • 用户
  5. 合并

    • 合并
  6. '慢'查询:

    (在我们构建的实际报告中,我们对角色,fachteam,团队,abteilung,bereich,geschaeftsbereich,konzernbereich进行了过滤)但是让我们通过这个声明来保持简单

    select 
        count(distinct CentralAccount) as 'aantal users',  
        count(distinct [Rol naam]) as 'aantal rollen',
        [FTM], [Fachteam], [TEM], [Team], 
        [ABT], [Abteilung], [BER], [Bereich], [GB], [Geschaeftsbereich],
        [KB], [Konzernbereich]
    from 
        [ODS_ISRC].[dbo].[Merge]
    where 
        CentralAccount is not null 
        and ftm is not null 
    group by 
        [FTM], [Fachteam], [TEM], [Team],
        [ABT], [Abteilung], [BER], [Bereich],
        [GB], [Geschaeftsbereich], [KB], [Konzernbereich]
    order by 
        count(distinct CentralAccount) desc
    

    什么是慢?

    当前执行时间为49-50秒(客户端统计信息)。

    我尝试过:

    我们已经有了一个群集密钥:ID, primary key, identity (1,1)

    查询统计信息显示它正在创建索引,因此我尝试预先创建此索引以便提高性能,我错了,它以某种方式花了5秒(10%)执行sql。

    create nonclustered index test
    on dbo.[Merge] (FTM, centralaccount)
    include ([Fachteam],[TEM],[Team],[ABT],[Abteilung],[BER],[Bereich],[GB],[Geschaeftsbereich],[KB],[Konzernbereich], [rol naam])
    

    问题:

    无论如何我可以在不预先创建表的情况下提高此查询的性能吗?

    额外信息:

    当数据填入报表过滤器时,查询会快速运行(可接受),但用户在过滤之前通常需要概述。

    执行计划:

    实际报告查询:

    select 
        count(distinct CentralAccount) as 'aantal users',  
        count(distinct [Rol naam]) as 'aantal rollen',
        [FTM], [Fachteam], [TEM], [Team],
        [ABT], [Abteilung], [BER], [Bereich],
        [GB], [Geschaeftsbereich], [KB], [Konzernbereich]
    from 
        [ODS_ISRC].[dbo].[Merge]
    where 
        CentralAccount is not null and ftm is not null 
        and (@Role = '' and ([Rol naam] like '%'+@Role+'%' or [Rol naam] is null)  
             or @Role = '' and (Role_Beschrijving like '%'+@Role+'%' or Role_Beschrijving is null) 
             or [Rol naam] like '%'+@Role+'%' or Role_Beschrijving like '%'+@Role+'%')
        and (@Team='' and (Team like '%'+@Team+'%' or Team is null) or
             @Team is not null and (Team like '%'+@Team+'%')or
             @Team is null and ( Team is null))
        and (@Fachteam='' and (Fachteam like '%'+@Fachteam+'%' or Fachteam is null) or
             @Fachteam is not null and (Fachteam like '%'+@Fachteam+'%')or
             @Fachteam is null and ( Fachteam is null))
        and (@Abteilung='' and (Abteilung like '%'+@Abteilung+'%' or Abteilung is null) or
             @Abteilung is not null and (Abteilung like '%'+@Abteilung+'%')or
             @Abteilung is null and ( Abteilung is null))
        and (@Bereich='' and (Bereich like '%'+@Bereich+'%' or Bereich is null) or
             @Bereich is not null and (Bereich like '%'+@Bereich+'%')or
             @Bereich is null and ( Bereich is null))
        and (@Geschaeftsbereich='' and (Geschaeftsbereich like  '%'+@Geschaeftsbereich+'%' or Geschaeftsbereich is null) or
             @Geschaeftsbereich is not null and (Geschaeftsbereich like   '%'+@Geschaeftsbereich+'%') or
             @Geschaeftsbereich is null and ( Geschaeftsbereich is null))
    group by 
        [FTM], [Fachteam], [TEM], [Team], [ABT], [Abteilung],
        [BER], [Bereich], [GB], [Geschaeftsbereich], [KB], [Konzernbereich]
    order by 
        count(distinct CentralAccount) desc
    

1 个答案:

答案 0 :(得分:1)

通过强迫parralelism我已经管理将执行时间减少到9秒,这是一个类似查询的例子,有3个计数;

select distinct
count(distinct a.CentralAccount) as 'Aantal users',
    'Aantal rollen'=(
        select count(distinct [Rol naam])  from DIM.Clean_KeyMerge b
        left join DIM.Clean_User dcub
            on(b.CentralAccount=dcub.CentralAccount) 
        where dcua.[Fachteam]=dcub.[Fachteam] and dcua.[Team]=dcub.[Team] and dcua.[Abteilung]=dcub.[Abteilung] and dcua.[Bereich]=dcub.[Bereich] and dcua.[Geschaeftsbereich]=dcub.[Geschaeftsbereich] 
    ),
    'Aantal entitlements'=(
        select count(distinct EntName)  from DIM.Clean_KeyMerge c
        left join DIM.Clean_User dcuc
            on(c.CentralAccount=dcuc.CentralAccount) 
        where dcua.[Fachteam]=dcuc.[Fachteam] and dcua.[Team]=dcuc.[Team] and dcua.[Abteilung]=dcuc.[Abteilung] and dcua.[Bereich]=dcuc.[Bereich] and dcua.[Geschaeftsbereich]=dcuc.[Geschaeftsbereich] 
    )
,dcua.[Fachteam],dcua.[Team],dcua.[Abteilung],dcua.[Bereich],dcua.[Geschaeftsbereich]from DIM.Clean_KeyMerge a
left join DIM.Clean_User dcua
    on(a.CentralAccount=dcua.CentralAccount)