2012-10-30 63 views
0

我需要查看/重構一個以一個表爲目標的現有存儲過程(10+行以上)。存儲過程簽名不能輕易更改,如下所示。在大型表上選擇查詢

存儲過程需要兩個由管道分隔的字符串,並使用SQL函數(SplitDelimitedVarChar)將字符串拆分爲臨時表,然後在實際選擇中使用該表。 數組中字符串的數量字符串的範圍從1到數千。

DateValueTimeValue列包含int表示行中的時間戳記。

我的問題是,如果任何人有任何IDE如果這是一個好(最好?)的解決方案,或者如果它可以做得更好。主要問題是它是否可以針對速度進行優化?

由於只能通過此存儲過程訪問表,因此索引與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 

回答

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)