2014-02-07 37 views
0

下面是該視圖的聲明:有什麼辦法可以加速這個MSSQL 2012視圖?

USE [calendar2014] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE view [dbo].[AdminRegisteredCards] WITH SCHEMABINDING as 
    SELECT ISNULL(ROW_NUMBER() 
    OVER (ORDER BY ta.CreatedOn, ta.ItemId), -1000) AS AdminRegisteredCardsId, 
    ta.ItemId, 
    ta.CardNumber, 
    ta.FirstName, 
    ta.LastName, 
    ta.Birthday, 
    ta.PostalCode, 
    ta.[Description], 
    ta.CardActivated, 
    ta.ContactInfo, 
    ta.PhoneNumber, 
    ta.ReceiveCalendarReminders, 
    ta.ReceiveGeneralMails, 
    ta.ReceivePrefStoreMails, 
    ta.CardStatus, 
    ta.SamoaCardId, 
    ta.CalendarUserId, 
    ta.LiveOpsRegistrantId, 
    ta.UseType, 
    ta.CreatedOn, 
    ta.ModifiedBy, 
    ta.ModifiedOn 
    from (
     SELECT CalendarUser.CalendarUserId as ItemId, 
     SamoaCard.CardNumber, 
     SamoaCard.FirstName, 
     SamoaCard.LastName, 
     CalendarUser.Birthday, 
     CalendarUser.PostalCode, 
     RegisterSourceType.[Description], 
     CalendarUserCard.CardActivated, 
     CalendarUser.EmailAddress as ContactInfo, 
     CalendarUser.PhoneNumber, 
     CalendarUser.ReceiveCalendarReminders, 
     CalendarUser.ReceiveGeneralMails, 
     CalendarUser.ReceivePrefStoreMails, 
     CASE WHEN CalendarUserCard.CardDeactivated IS NOT NULL THEN 'Deactivated' ELSE 'Activated' END AS CardStatus, 
     SamoaCard.SamoaCardId, 
     CalendarUser.CalendarUserId, 
     null as LiveOpsRegistrantId, 
     SamoaCard.CreatedOn, 
     'C' as UseType, 
     CalendarUser.ModifiedBy, 
     CalendarUser.ModifiedOn 
     FROM dbo.CalendarUser CalendarUser 
     INNER JOIN dbo.RegisterSourceType RegisterSourceType 
      ON CalendarUser.RegisterType = RegisterSourceType.RegisterType 
     INNER JOIN dbo.CalendarUserCard CalendarUserCard 
      ON CalendarUserCard.CalendarUserId = CalendarUser.CalendarUserId 
     INNER JOIN dbo.SamoaCard SamoaCard 
      ON CalendarUserCard.SamoaCardId = SamoaCard.SamoaCardId 

     UNION ALL 

     SELECT LiveOpsRegistrant.LiveOpsRegistrantId as ItemId, 
      LiveOpsRegistrant.CardNumber, 
      'Registered' as FirstName, 
      'Card' as LastName, 
      LiveOpsRegistrant.Birthday, 
      null as PostalCode, 
      'LiveOps' as Description, 
      LiveOpsRegistrant.CreatedOn as CardActivated, 
      LiveOpsRegistrant.PhoneNumber as ContactInfo, 
      LiveOpsRegistrant.PhoneNumber, 
      CONVERT(bit,0) as ReceiveCalendarReminders, 
      CONVERT(bit,0) as ReceiveGeneralMails, 
      CONVERT(bit,0) as ReceivePrefStoreMails, 
      'Activated' AS CardStatus, 
      SamoaCard.SamoaCardId, 
      null as CalendarUserId, 
      LiveOpsRegistrant.LiveOpsRegistrantId, 
      SamoaCard.CreatedOn, 
      'L' as UseType, 
      SamoaCard.ModifiedBy, 
      SamoaCard.ModifiedOn 
     FROM dbo.LiveOpsRegistrant LiveOpsRegistrant 
     INNER JOIN dbo.SamoaCard SamoaCard 
      ON LiveOpsRegistrant.CardNumber = SamoaCard.CardNumber 
    ) ta; 

目前,這一觀點正在採取長的時間才能獲得 - 我們有大約140萬的記錄。

有什麼方法可以優化這個視圖嗎?

+0

@SaUce - 這不太準確。嵌套的子查詢有可能成爲一個問題。如果OP使用SQL Server的新版本,公用表表達式可能會有所幫助。 –

+0

@JustinNiessner:是的,我正在使用MSSQL 2012. – sergserg

+3

'JOIN ON'子句中的額外括號不是必需的,可能有點混淆。你爲什麼要用'ROW_NUMBER()'使用'ISNULL'? – NickyvV

回答

0
USE [calendar2014] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE view [dbo].[AdminRegisteredCards] 


    WITH inCalender AS(
     SELECT CalendarUser.CalendarUserId as ItemId, 
     SamoaCard.CardNumber, 
     SamoaCard.FirstName, 
     SamoaCard.LastName, 
     CalendarUser.Birthday, 
     CalendarUser.PostalCode, 
     RegisterSourceType.[Description], 
     CalendarUserCard.CardActivated, 
     CalendarUser.EmailAddress as ContactInfo, 
     CalendarUser.PhoneNumber, 
     CalendarUser.ReceiveCalendarReminders, 
     CalendarUser.ReceiveGeneralMails, 
     CalendarUser.ReceivePrefStoreMails, 
     CASE WHEN CalendarUserCard.CardDeactivated IS NOT NULL THEN 'Deactivated' ELSE 'Activated' END AS CardStatus, 
     SamoaCard.SamoaCardId, 
     CalendarUser.CalendarUserId, 
     null as LiveOpsRegistrantId, 
     SamoaCard.CreatedOn, 
     'C' as UseType, 
     CalendarUser.ModifiedBy, 
     CalendarUser.ModifiedOn 
     FROM dbo.CalendarUser CalendarUser 
     INNER JOIN dbo.RegisterSourceType RegisterSourceType 
      ON CalendarUser.RegisterType = RegisterSourceType.RegisterType 
     INNER JOIN dbo.CalendarUserCard CalendarUserCard 
      ON CalendarUserCard.CalendarUserId = CalendarUser.CalendarUserId 
     INNER JOIN dbo.SamoaCard SamoaCard 
      ON CalendarUserCard.SamoaCardId = SamoaCard.SamoaCardId 
),inLive AS(

     SELECT LiveOpsRegistrant.LiveOpsRegistrantId as ItemId, 
      LiveOpsRegistrant.CardNumber, 
      'Registered' as FirstName, 
      'Card' as LastName, 
      LiveOpsRegistrant.Birthday, 
      null as PostalCode, 
      'LiveOps' as Description, 
      LiveOpsRegistrant.CreatedOn as CardActivated, 
      LiveOpsRegistrant.PhoneNumber as ContactInfo, 
      LiveOpsRegistrant.PhoneNumber, 
      CONVERT(bit,0) as ReceiveCalendarReminders, 
      CONVERT(bit,0) as ReceiveGeneralMails, 
      CONVERT(bit,0) as ReceivePrefStoreMails, 
      'Activated' AS CardStatus, 
      SamoaCard.SamoaCardId, 
      null as CalendarUserId, 
      LiveOpsRegistrant.LiveOpsRegistrantId, 
      SamoaCard.CreatedOn, 
      'L' as UseType, 
      SamoaCard.ModifiedBy, 
      SamoaCard.ModifiedOn 
     FROM dbo.LiveOpsRegistrant LiveOpsRegistrant 
     INNER JOIN dbo.SamoaCard SamoaCard 
      ON LiveOpsRegistrant.CardNumber = SamoaCard.CardNumber 
    ) 

    Select 
ISNULL(ROW_NUMBER() 
    OVER (ORDER BY I.CreatedOn, I.ItemId), -1000) AS AdminRegisteredCardsId, 
    I.ItemId, 
    I.CardNumber, 
    I.FirstName, 
    I.LastName, 
    I.Birthday, 
    I.PostalCode, 
    I.[Description], 
    I.CardActivated, 
    I.ContactInfo, 
    I.PhoneNumber, 
    I.ReceiveCalendarReminders, 
    I.ReceiveGeneralMails, 
    I.ReceivePrefStoreMails, 
    I.CardStatus, 
    I.SamoaCardId, 
    I.CalendarUserId, 
    I.LiveOpsRegistrantId, 
    I.UseType, 
    I.CreatedOn, 
    I.ModifiedBy, 
    I.ModifiedOn 
    from inCalender I Left outer join 
    inLive L on I.ItemId = L.CardNumber 

注:
基於我認爲我寫的。我不知道應該作爲連接的一部分使用什麼鍵。它可以相應地完成。 如果您獲取任何重複記錄,請不要驚訝,以便您可以在select語句中加入獨特的內容,或者加入適當的加入,以解決該問題。

+0

你建議在原始查詢中有「Union ALL」的「Left Outer Join」? –

0

正如我在評論中提到的那樣,如果你能找到我,這些細節將很樂意查看它,看看我們是否可以進一步優化它。這意味着在這裏小規模的例子來說明我是如何計劃用「全外聯接」取代「聯盟全部」

去這種方法的原因是這只是一次選擇,你不會有任何子查詢。所以沒有內部查詢檢索數據的開銷並將其傳遞給查詢。

你可以看到,我認爲我的一個意見之一是在這個例子中下實現,「在表SamoaCard有沒有單列將在同一時間在兩列SamoaCardId和CardNumber值」

DECLARE @CalendarUserCard TABLE 
    (
     SamoaCardId INT NOT NULL 
     ,name  sysname NOT NULL 
    ) 

    DECLARE @LiveOpsRegistrant TABLE 
    (
     CardNumber    INT NOT NULL 
     ,LiveOpsRegistrantId sysname NOT NULL 
    ) 

    DECLARE @SamoaCard TABLE 
    (
     SamoaCardId  INT NULL 
     ,CardNumber   INT NULL 

    ) 

    INSERT INTO @CalendarUserCard (SamoaCardId, name) SELECT 1,'CalendarUserCard 1' UNION ALL SELECT 2,'CalendarUserCard 2' 
    INSERT INTO @LiveOpsRegistrant (CardNumber, LiveOpsRegistrantId) SELECT 3,'LiveOpsRegistrantId 3' UNION ALL SELECT 4,'LiveOpsRegistrantId 4' 
    INSERT INTO @SamoaCard (SamoaCardId,CardNumber ) SELECT 1,NULL UNION ALL SELECT 2,NULL UNION ALL SELECT NULL,3 UNION ALL SELECT NULL,4 

    SELECT * FROM @CalendarUserCard 
    SELECT * FROM @LiveOpsRegistrant 
    SELECT * FROM @SamoaCard 

    SELECT 
     CASE 
      WHEN SamoaCard.SamoaCardId IS NULL THEN 'Value From LiveOpsRegistrant' 
      WHEN SamoaCard.CardNumber IS NULL THEN 'Value From CalendarUserCard' 
     END TestAttributeColumn 
     ,CASE 
      WHEN SamoaCard.SamoaCardId IS NULL THEN 'Registered' 
      WHEN SamoaCard.CardNumber IS NULL THEN CalendarUserCard.name 
     END FirstName 
     ,CASE 
      WHEN SamoaCard.SamoaCardId IS NULL THEN 'L' 
      WHEN SamoaCard.CardNumber IS NULL THEN 'C' 
     END UseType 
     ,CASE 
      WHEN SamoaCard.SamoaCardId IS NULL THEN LiveOpsRegistrant.LiveOpsRegistrantId 
      WHEN SamoaCard.CardNumber IS NULL THEN NULL 
     END AS LiveOpsRegistrantId 
    FROM @CalendarUserCard CalendarUserCard 
    INNER JOIN @SamoaCard SamoaCard 
     ON CalendarUserCard.SamoaCardId = SamoaCard.SamoaCardId 
    FULL OUTER JOIN @LiveOpsRegistrant LiveOpsRegistrant 
     ON SamoaCard.CardNumber = LiveOpsRegistrant.CardNumber 

enter image description here

相關問題