2017-07-13 5 views
3

現在、SQL Server 2016 Enterpriseで奇妙な動作をするとパフォーマンスが低下するという問題が発生しています。SQL Server上のビューにクエリを実行する際にパフォーマンスの問題が発生する

データベースに新しいスキーマを作成し、このスキーマ内にビューを作成しました。今

、私はこのスキーマおよびビューを含むデータベースに直接接続し、

SELECT * FROM SCHEMA.VIEW 

のような単純なクエリを記述する場合、それが完了するまでに約30分を(!)かかります。同じことが

SELECT * FROM DB_NAME.SCHEMA.VIEW 

ような完全修飾クエリで発生しかし、私が最初に習得するには、データベースまたは別のユーザーデータベースを変更してデータベース間で再クエリを実行した場合、今、それは約10秒以内に完了しました(!) 。両方のデータベースのデータベースプロパティーは同じですが、データベースファイルとログファイルに使用されるドライブも同じです。

この巨大なパフォーマンス上の問題を引き起こす可能性のあるものについて誰かが考えていますか?

CREATE VIEW [controlling].[UnitLoginHistory] 
AS 

    WITH cte 
      ( 
        Jahr, UnityId, Unit_UnityId, Analytical_Code, Unit_Code, Unit_Name, Active 
      ,  Show_in_org_chart, Begin_Date, End_Date, Unit_Owner_First_Name, Unit_Owner_Last_Name 
      ,  Unit_Owner_Login, Unit_Owner_CorporateID, UnityParentId, UnityTypeId, Unit_Level 
      ,  Magnitude_Code, ImportDate, ReplicationLevel 
      ) 
    AS 
    (
      SELECT 
        dt.Jahr 
      ,  a.UnityId 
      ,  a.UnityId 
      ,  a.Analytical_Code 
      ,  a.Unit_Code 
      ,  a.Unit_Name 
      ,  cast(case when a.Active = 'True' then 1 else 0 end as bit) 
      ,  a.Show_in_org_chart 
      ,  a.Begin_Date 
      ,  a.End_Date 
      ,  a.Unit_Owner_First_Name 
      ,  a.Unit_Owner_Last_Name 
      ,  a.Unit_Owner_Login 
      ,  a.Unit_Owner_CorporateID 
      ,  a.UnityParentId 
      ,  a.UnityTypeId 
      ,  a.Unit_Level 
      ,  a.Magnitude_Code 
      ,  a.ImportDate 
      ,  1 
      FROM [Staging_INPUT].[DBO].[OBS_Workunit] a 
      JOIN (
          SELECT 
            YEAR(IMPORTDATE)  Jahr 
          ,  MAX(IMPORTDATE)   Datum 
          FROM [Staging_INPUT].[DBO].[OBS_Workunit] 
          GROUP BY 
            YEAR(IMPORTDATE) 
        )          dt 
      ON  a.ImportDate     =  dt.datum 
      WHERE a.unitytypeid     =  12 
      UNION ALL 
      SELECT 
        b.Jahr 
      ,  b.UnityId 
      ,  a.UnityId 
      ,  b.Analytical_Code 
      ,  a.Unit_Code 
      ,  a.Unit_Name 
      ,  cast(case when a.Active = 'True' then 1 else 0 end as bit) 
      ,  a.Show_in_org_chart 
      ,  a.Begin_Date 
      ,  a.End_Date 
      ,  a.Unit_Owner_First_Name 
      ,  a.Unit_Owner_Last_Name 
      ,  a.Unit_Owner_Login  
      ,  a.Unit_Owner_CorporateID 
      ,  a.UnityParentId 
      ,  a.UnityTypeId 
      ,  a.Unit_Level 
      ,  a.Magnitude_Code 
      ,  a.ImportDate 
      ,  b.ReplicationLevel + 1 
      FROM [Staging_INPUT].[DBO].[OBS_Workunit] a 
      JOIN cte          b 
      ON  a.UnityId      =  b.UnityParentId 
      AND  a.ImportDate     =  b.ImportDate 
      AND  a.UnityTypeId     >=  6 
    ) 
    ,  Company 
    AS 
    (
      SELECT DISTINCT 
        Jahr 
      ,  UnityId 
      ,  LEFT(REPLACE(Magnitude_Code,'XE','U'),4) CompanyUID 
      FROM cte 
      WHERE UnityTypeId  =  7 
      AND  Active   =  1 

    ) 
    ,  BUs 
    AS 
    (
      SELECT DISTINCT 
        a.Jahr       JAHR 
      ,  a.UnityId      UnityId 
      ,  c.Analytical_Code    BU_CODE 
      ,  c.Unit_Name      BU_NAME 
      ,  b.CompanyUID 
      FROM cte      a 

      JOIN Company     b 
      ON  a.Jahr   =  b.Jahr 
      AND  a.UnityId  =  b.UnityId 
      AND  a.Active  =  1 

      JOIN cte      c 
      ON  a.Jahr   =  c.Jahr 
      AND  a.UnityId  =  c.Unit_UnityId 
      AND  c.Active  =  1 

      WHERE ISNULL(c.Analytical_Code,'') != '' 
    ) 
    SELECT DISTINCT 
      a.JAHR       JAHR 
    ,  a.BU_CODE      BU_CODE 
    ,  a.BU_NAME      BU_NAME 
    ,  'EUROPE\' 
    +  b.Unit_Owner_Login    BU_LOGIN 
    ,  b.Unit_Owner_Last_Name 
    +  ', ' 
    +  b.Unit_Owner_First_Name   BU_LOGIN_NAME 
    ,  a.CompanyUID     COMPANY_UID 
    FROM BUs        a 

    JOIN cte        b 
    ON  a.Jahr     =  b.Jahr 
    AND  a.UnityId    =  b.UnityId 
    AND  b.Active    =  1 

    UNION 

    SELECT DISTINCT 
      a.Jahr       JAHR 
    ,  a.BU_CODE      BU_CODE 
    ,  a.BU_NAME      BU_NAME 
    ,  c.BU_LOGIN      BU_LOGIN 
    ,  c.BU_LOGIN_NAME     BU_LOGIN_NAME 
    ,  a.CompanyUID     COMPANY_UID 
    FROM BUs        a 

    CROSS JOIN (
        SELECT DISTINCT 
          [Last Name]  COLLATE Latin1_General_100_CI_AS 
        +  ', ' 
        +  [First Name] COLLATE Latin1_General_100_CI_AS BU_LOGIN_NAME 
        ,  'EUROPE\' 
        +  [User Id]  COLLATE Latin1_General_100_CI_AS BU_LOGIN 
        FROM NAVISION.dbo.Employee 
        WHERE [Global Dimension 2 Code]  IN  (
                      10061 
                    ,  10062 
                    ) 
        AND  ISNULL([User Id],'')   !=  '' 
       )       c 

GO 

実行時間と統計:

use NAVISION 

GO 

set statistics io on 
set statistics time on 

select * 
from NAVISION.dbo.UnitLoginHistory 
where Jahr = 2017 
order by 1,2 

SQL Serverの解析およびコンパイル時間: CPU時間= 0秒、経過時間= 0

Iは、ビューの次のコードを使用しましたミズ。

(34119行が該当) テーブル「ワークテーブル」。スキャンカウント1607、論理読取り253696、物理読取り0、先読み読取り1238、読取り論理読取り0、ロブ物理読取り0、読込み先読み0である。 表 'U415 Altran Engineering GmbH $従業員'。スキャンカウント1、論理読み取り128、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。 テーブル 'U388 Altran Aviation GmbH $ Employee'。スキャンカウント1、論理読取り42、物理読取り0、読取り先読み0、論理読取り0、論理読取り0、論理読取り0、読込み先読み0。 表 'U354 Altran Service GmbH $従業員'。スキャンカウント1、論理読み取り210、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。 テーブル 'U353 AIH Holding GmbH Co KG $従業員'。スキャンカウント1、論理読み取り934、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み0である。 テーブル 'OBS_Workunit'。スキャン回数46286、論理読み取り10430933、物理読み取り0、先読み読み取り0、論理読み取り0、論理読み取り0、論理読み取り0、論理読み取り0、論理読み取り0、論理読み取り0のLOB先読み0

SQL Server実行時間: CPU時間= 1363546 ms 、経過時間= 1455980ms。

use Staging_INPUT 
GO 

set statistics io on 
set statistics time on 

select * 
from NAVISION.dbo.UnitLoginHistory 
where Jahr = 2017 
order by 1,2 

SQL Serverの解析およびコンパイル時: CPU時間= 0ミリ秒、経過時間= 0ミリ秒。

(34119行が該当) テーブル「ワークテーブル」。スキャンカウント582、論理読取り576096、物理読取り0、先読み読取り146、論理読取り0、論理読取り0、論理読取りLOB先読み0である。 テーブル 'ワークファイル'。スキャンカウント0、論理読取り0、物理読取り0、先読み読取り0、論理読取り0、論理読取り0、論理読込みLOB先読み0。 表 'OBS_Workunit'。スキャンカウント53573、論理読取り485656、物理読取り0、読取り先読み0、論理読取り0、論理読取り0、論理読取り0、読込み先読み0である。 表 'U415 Altran Engineering GmbH $従業員'。スキャンカウント1、論理読み取り128、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。 テーブル 'U388 Altran Aviation GmbH $ Employee'。スキャンカウント1、論理読取り42、物理読取り0、読取り先読み0、論理読取り0、論理読取り0、論理読取り0、読込み先読み0。 表 'U354 Altran Service GmbH $従業員'。スキャンカウント1、論理読み取り210、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。 テーブル 'U353 AIH Holding GmbH Co KG $従業員'。スキャンカウント1、論理読み取り934、物理読み取り0、先読み読み取り0、論理読み取り0、論理読み取り0、論理読み取り0、読み取り先読みLOB 0

SQL Server実行時間: CPU時間= 15047 ms 、経過時間= 28007ms。

+3

投稿コード – JPF

+0

これはかなり複雑なようです。 –

+0

これはクエリの獣です。それは初めてのことですが、それはちょうどそれが使用する正しい計画を考え出していたときにかかりましたか?つまり、データベースを変更したところ、OKを実行したように見えました。コンパイル時のコンポーネントがないことを確認するために同じデータベースで2回実行してみましたか? – Xedni

答えて

0

実行計画が異なるため、パフォーマンスが異なる必要があります。計画はデータベースのコンテキストによって異なるため、計画に影響するさまざまな設定が示唆されています。デフォルトのSETオプションとプロパティは非常に多く、データベースによって異なる場合があります.1つまたは2つ欠けています。

2データベースのスクリプトをCREATE DATABASE生成し、スクリプトを比較することをお勧めします。

EDIT:

database compatibility level設定の違いは、実行計画に影響を与えることができます。 LEGACY_CARDINALITY_ESTIMATIONデータベーススコープの設定が有効になっていない限り、SQL Serverは110(SQL Server 2012)レベルのデータベースにレガシーカーディナリティ推定を使用しますが、新しいCEは120以降のデータベースに使用されます。

+0

これは質問には答えません。コメントでなければなりません。 – CodingYoshi

+0

@コーディングよし、なぜこれが答えではないでしょうか?異なるプランのみがこれらの症状を引き起こし、データベースの状況によって異なるプランは、データベース設定/プロパティー、AFAIKによるものでなければなりません。 –

+0

CREATE DATABASEスクリプトの互換性レベルは、NAVISIONの場合は130、Staging_INPUTの場合は110、NAVISIONの場合はSQL Server 2016、Staging_INPUTの場合はSQL Server 2012となります。もう1つの違いは、回復モードで、NAVISIONではSIMPLE、Staging_INPUTではFULLに設定されています。他のすべてのオプションはまったく同じです –

関連する問題