以下是视图的声明:
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 :(得分: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语句中添加一个distinct,或者通过适当的连接加入,这将解决问题。
答案 1 :(得分:0)
正如我在评论中提到的,如果你能告诉我这些细节,我们很乐意看一下它,看看我们是否可以进一步优化它。这里是一个较小比例的例子来说明我是如何计划用“FULL OUTER JOIN”取代“UNION ALL”
采用这种方法的原因是这只是一次选择,你不会有任何子查询。因此,不需要保留内部查询检索数据的开销,并将其传递给查询。
你可以看到我假设我的一条评论在下面的例子中是正确的,“在表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