我需要检查/重构一个以表格为目标的现有存储过程(10多万行)。存储过程签名不能轻易更改,如下所示。
存储过程采用由管道分隔的两个字符串,并使用SQL函数(SplitDelimitedVarChar
)将字符串拆分为临时表,然后在实际的select中使用。 array 字符串中的字符串数量范围为1到数千。
DateValue
和TimeValue
列包含行中时间戳的int
表示。
我的问题是,如果任何人有任何想法,如果这是一个好的(最好的?)解决方案,或者它可以做得更好。主要问题是它是否可以针对速度进行优化?
由于该表只能通过此存储过程访问,因此索引是非聚类的WHERE
列,并包含所有SELECT
列。
感谢您提出任何建议或指示。
CREATE PROCEDURE [dbo].[spdata_Get_Ana]
@beginTime INT,
@endTime INT,
@subscribers VARCHAR(MAX),
@exchanges VARCHAR(MAX) = '1:',
@beginDateValue int,
@endDateValue int,
@target int = 1
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #exch (Item Varchar(20) COLLATE database_default)
INSERT INTO #exch
SELECT Item FROM [SplitDelimitedVarChar] (@exchanges, '|') ORDER BY Item
CREATE CLUSTERED INDEX idx ON #exch (Item)
CREATE TABLE #subs (Item Varchar(20) COLLATE database_default)
INSERT INTO #subs
SELECT Item FROM [SplitDelimitedVarChar] (@subscribers, '|') ORDER BY Item
CREATE CLUSTERED INDEX idx ON #subs (Item)
SELECT
[Id]
,'' AS 'Name'
,[NameId]
,[Level]
,[Ne]
,[CallId]
,[Bg]
,[DateTime]
,[TimeStamp]
,[LogOwnerSnb]
,[TypeOfLog]
,[AbsenceCode]
,[AnswerTime]
,[CallForwardingReason]
,[CallForwardingToNumber]
,[CallTransferTime]
,[CallTransferReason]
,[SeizedSubscriberType]
,[SeizedSubscriberTime]
,[SeizedSubscriberNumber]
,[CalledSubscriberService]
,[InSubscriberType]
,[InSubscriberNumber]
,[CallDirection]
,[SubscriberService]
,[ClearingCause]
,[ClearingCauseTime]
,[OnHookTime]
,[OutAnswerSubType]
,[OutAnswerTime]
,[OutAnswerSubNum]
,[RingingStartedTime]
,[ReroutedToNumber]
,[InitiatedService]
,[B26]
FROM [dbo].[data_centrex_Ana] AS A
WHERE
(A.[DateValue] BETWEEN @beginDateValue AND @endDateValue)
AND
EXISTS(SELECT [Item] FROM #exch WHERE [Item] = A.[Level])
AND
(A.[TimeValue] BETWEEN @beginTime AND @endTime)
AND
(
(@target = 1 AND EXISTS(SELECT [Item] FROM #subs WHERE [Item] = A.[LogOwnerSnb]))
OR
(@target = 2 AND EXISTS(SELECT [Item] FROM #subs WHERE [Item] = A.[Bg]))
)
END
答案 0 :(得分:1)
怀疑在索引中包含选择列有什么好处 它只是一个大指数。
尝试加入
SELECT [Id]
FROM [dbo].[data_centrex_Ana] AS A
JOIN #exch
ON [Item] = A.[Level]
JOIN #subs
ON (@target = 1 AND [Item] = A.[LogOwnerSnb])
OR (@target = 2 AND [Item] = A.[Bg])
WHERE
(A.[DateValue] BETWEEN @beginDateValue AND @endDateValue)
AND (A.[TimeValue] BETWEEN @beginTime AND @endTime)