-1

私は非常に遅いビューを持っています:

ALTER  view [dbo].[TAT] as
WITH d AS ( SELECT TAT = CASE WHEN TAT > 191 THEN 192 ELSE TAT END,
   [MONTH entered],
   [YEAR] = DATEPART(yyyy,[datetime entered])
  FROM [SalesDWH].[dbo].[TurnAround] TurnAround
  left outer join hermes.lom.dbo.lom_specimen Lom
  on TurnAround.[specimen id] = lom.specimen
  LEFT outer join SalesDWH.dbo.Isomers Isomers
  on TurnAround.[specimen id] = Isomers.[accession id]
  WHERE lom.specimen is null
  and isomers.[accession id] is null
 -- GROUP BY CASE WHEN TAT > 191 THEN 192 ELSE TAT END 
    --[datetime entered],[Month Entered]
),
n AS ( SELECT TOP (192) n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
  FROM sys.all_columns ORDER BY [object_id]
)
SELECT TAT = n.n,

  [MONTH entered],
  [YEAR]

FROM n LEFT OUTER JOIN d 
ON n.n = d.TAT  



GO

実行計画を見ると、SORTING であるステップの 1 つに 70% のコストがかかることがわかります。

SORTING ステップを調べると、ORDER BY は次のように表示されます。

[SalesDWH].[dbo].[QuickLabDump].Specimen ID Ascending, [SalesDWH].[dbo].[QuickLabDump].Date Entered Ascending, [SalesDWH].[dbo].[QuickLabDump].Time Entered Ascending, [SalesDWH].[dbo].[QuickLabDump].Date Completed Ascending, [SalesDWH].[dbo].[QuickLabDump].Time Completed Ascending, [SalesDWH].[dbo].[QuickLabDump].Practice Name Ascending, [SalesDWH].[dbo].[QuickLabDump].Practice Code Ascending, [SalesDWH].[dbo].[QuickLabDump].Order Count Ascending, [SalesDWH].[dbo].[QLMLISMapping].MLIS Practice ID Ascending, [SalesDWH].[dbo].[adjustedtime].TimeDifference Ascending

しかし、どこにも ORDER BY を指定していません。

質問:

  1. ORDER BY がないのに、ORDER BY が ASCENDING と表示されるのはなぜですか?
  2. このビューを高速化するにはどうすればよいですか?

この情報が必要かどうかはわかりませんが、上記のビューは という別のビューを照会していますTURNAROUND:

USE [SalesDWH]
GO

/****** Object:  View [dbo].[TurnAround]    Script Date: 05/25/2012 15:32:08 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO




ALTER VIEW [dbo].[TurnAround]
AS
SELECT     dbo.QuickLabDump.[Specimen ID], DATEPART(yyyy, dbo.QuickLabDump.[Date Entered]) AS [Year Entered], CAST(CAST(dbo.QuickLabDump.[Date Entered] AS DATE) 
                      AS DATETIME) + CAST(dbo.QuickLabDump.[Time Entered] AS TIME) AS [DateTime Entered], CAST(CAST(dbo.QuickLabDump.[Date Completed] AS DATE) AS DATETIME) 
                      + CAST(dbo.QuickLabDump.[Time Completed] AS TIME) AS [DateTime Completed], dbo.QuickLabDump.[Practice Code] AS [QL Practuce Code], 
                      dbo.QLMLISMapping.[MLIS Practice ID], DATEPART(m, dbo.QuickLabDump.[Date Entered]) AS [Month Entered], ROUND(CAST(DATEDIFF(mi, 
                      CAST(CAST(dbo.QuickLabDump.[Date Entered] AS DATE) AS DATETIME) + CAST(dbo.QuickLabDump.[Time Entered] AS TIME), 
                      CAST(CAST(dbo.QuickLabDump.[Date Completed] AS DATE) AS DATETIME) + CAST(dbo.QuickLabDump.[Time Completed] AS TIME)) AS FLOAT) / 60, 0) AS TAT, 
                      ROUND(CAST(DATEDIFF(mi, CAST(CAST(dbo.QuickLabDump.[Date Entered] AS DATE) AS DATETIME) + CAST('9:00AM' AS TIME), 


                      CAST(CAST(dbo.QuickLabDump.[Date Completed] AS DATE) AS DATETIME) 
                      + CAST(dbo.QuickLabDump.[Time Completed] AS TIME)) AS float) / 60, 0) 

                      AS [Hours TurnAround Since 9AM], TAT9AMStateAdjusted=                   



                      ROUND(CAST(DATEDIFF(mi, CAST(CAST(dbo.QuickLabDump.[Date Entered] AS DATE) AS DATETIME) 
                      + CAST('9:00AM' AS TIME),                                            
                      CAST(CAST(dbo.QuickLabDump.[Date Completed] AS DATE) AS DATETIME) 
                      + CAST(dbo.QuickLabDump.[Time Completed] AS TIME)) AS float) / 60, 0)                         


                      +dbo.adjustedtime.timedifference
                      ,dbo.QuickLabDump.[Order Count], CONVERT(VARCHAR(8), DATEADD(D, - (1 * DATEPART(dw, dbo.QuickLabDump.[Date Entered])) + 6,
                       dbo.QuickLabDump.[Date Entered]), 1) AS [Week Ending]
FROM         dbo.QuickLabDump 
             INNER JOIN dbo.QLMLISMapping 
             ON dbo.QuickLabDump.[Practice Code] = dbo.QLMLISMapping.[Quicklab ID]
             left outer join dbo.AccountState
             on dbo.QuickLabDump.[Practice Code]=dbo.AccountState.[Account]
             left outer join dbo.AdjustedTime 
             ON dbo.AccountState.[state]=dbo.adjustedtime.[state]
WHERE     (dbo.QuickLabDump.[Practice Code] NOT LIKE 'test%') AND (dbo.QuickLabDump.[Specimen ID] NOT LIKE 'of%') AND (dbo.QuickLabDump.Outcome <> 'rejected')
GROUP BY dbo.QuickLabDump.[Specimen ID], dbo.QuickLabDump.[Date Entered], dbo.QuickLabDump.[Time Entered], dbo.QuickLabDump.[Date Completed], 
                      dbo.QuickLabDump.[Time Completed], dbo.QuickLabDump.[Practice Name], dbo.QuickLabDump.[Practice Code], dbo.QuickLabDump.[Order Count], 
                      dbo.QLMLISMapping.[MLIS Practice ID],dbo.adjustedtime.timedifference
HAVING      (dbo.QuickLabDump.[Order Count] = MAX(dbo.QuickLabDump.[Order Count])) OR
                      (dbo.QuickLabDump.[Order Count] IS NULL)




GO

テーブルの定義は次のとおりです。

CREATE TABLE [dbo].[QuickLabDump](
    [Specimen ID] [varchar](50) NULL,
    [Client Key] [int] NULL,
    [Outcome] [varchar](50) NULL,
    [Medications] [varchar](max) NULL,
    [Date Collected] [date] NULL,
    [Time Collected] [time](0) NULL,
    [Date Entered] [date] NULL,
    [Time Entered] [time](0) NULL,
    [Date Completed] [date] NULL,
    [Time Completed] [time](0) NULL,
    [Test Date] [date] NULL,
    [Test Time] [time](0) NULL,
    [Practice Name] [varchar](500) NULL,
    [Practice Code] [varchar](50) NULL,
    [Requesting Physician] [varchar](500) NULL,
    [Other Medications] [varchar](max) NULL,
    [Order Comments] [varchar](max) NULL,
    [Reference Number] [varchar](500) NULL,
    [Order Count] [int] NULL,
    [QuickLabDumpID] [int] NOT NULL,
    [Source] [varchar](50) NULL,
    [MLIS] [varchar](50) NULL,
 CONSTRAINT [PK_QuickLabDump_1] PRIMARY KEY CLUSTERED 
(
    [QuickLabDumpID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
4

4 に答える 4

2

並べ替えられた列は、TurnAroundのGROUP BY句の列です。を実行する最も簡単な方法GROUP BYは、最初にグループ列で並べ替え、次にグループごとに行を分割し、最後にグループごとの集計を計算することです。この場合、まさにそれがDBが行っていることのように見えます。

于 2012-05-25T22:39:32.267 に答える
2

クエリ アナライザーは、Group BY で並べ替えが行われていることを示しています。

パフォーマンスを向上させるために、group by が使用しているフィールドでインデックスをテスト\作成する必要があります。

Group By で並べ替えを作成する方法について詳しく説明します。リンク

于 2012-05-25T22:43:51.390 に答える
2

グループ化および(外部)結合がソートの原因である可能性があります。使用している列に一致するインデックスがありますか? テーブルの完全な定義 (インデックスとキー/制約を含む) を投稿すると、問題を見つけるのに当て推量が少なくなります。

于 2012-05-25T22:40:38.487 に答える
1

念のために言っておきますが、注文は次のとおりです。

,
n AS ( SELECT TOP (192) n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
  FROM sys.all_columns ORDER BY [object_id]
)
于 2012-05-25T22:36:08.207 に答える