2010-03-17 12 views
6

मैंने एक संग्रहित प्रक्रिया लिखी है, जिसे कल, आमतौर पर एक सेकंड के तहत पूरा किया जाता है। आज, इसमें लगभग 18 सेकंड लगते हैं। मैं कल भी समस्या में भाग गया, और यह ड्रॉपिंग और संग्रहीत प्रक्रिया को फिर से तैयार करके हल किया जाना प्रतीत होता था। आज, वह चाल काम नहीं कर रही है। :(एसक्यूएल सर्वर - संग्रहीत प्रक्रिया अचानक धीमी हो जाती है

दिलचस्प बात यह है कि अगर मैं संग्रहीत प्रक्रिया के शरीर को कॉपी करें और एक सीधा क्वेरी इसे जल्दी पूरा करता है के रूप में यह निष्पादित करें। यह तथ्य यह है कि यह एक संग्रहीत प्रक्रिया है कि उसे धीमा ...!

है प्रतीत हो रहा है

क्या कोई जानता है कि समस्या क्या हो सकती है? मैंने जवाबों की खोज की है, लेकिन अक्सर वे क्वेरी विश्लेषक के माध्यम से इसे चलाने की सलाह देते हैं, लेकिन मेरे पास यह नहीं है - मैं अब के लिए SQL Server 2008 एक्सप्रेस का उपयोग कर रहा हूं।

संग्रहित प्रक्रिया निम्नानुसार है;

 
ALTER PROCEDURE [dbo].[spGetPOIs] 
    @lat1 float, 
    @lon1 float, 
    @lat2 float, 
    @lon2 float, 
    @minLOD tinyint, 
    @maxLOD tinyint, 
    @exact bit 
AS 
BEGIN 
    -- Create the query rectangle as a polygon 
    DECLARE @bounds geography; 
    SET @bounds = dbo.fnGetRectangleGeographyFromLatLons(@lat1, @lon1, @lat2, @lon2); 

    -- Perform the selection 
    if (@exact = 0) 
    BEGIN 
     SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID] 
     FROM [POIs] 
     WHERE 
      NOT ((@maxLOD [MaxLOD])) AND 
      (@bounds.Filter([Location]) = 1) 
    END 
    ELSE 
    BEGIN 
     SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID] 
     FROM [POIs] 
     WHERE 
      NOT ((@maxLOD [MaxLOD])) AND 
      (@bounds.STIntersects([Location]) = 1) 
    END 

END

'पीओआई' तालिका में मिनीलोड, मैक्सएलडी, और स्थान पर एक स्थानिक सूचकांक पर एक सूचकांक है।

उत्तर

3

आह, क्या यह क्वेरी प्लान बेकार हो सकता है?

एसपी का संकलन/क्वेरी एलपीएन पहले उपयोग पर निर्धारित होता है - पैरामीटर के आधार पर। इसलिए, पहली कॉल के पैरामीटर (जब कोई एलपीएन मौजूद नहीं है) क्वेरी प्लान निर्धारित करते हैं। एक पियोनट में मुझे कैश से गिरा दिया जाता है, नई योजना उत्पन्न होती है।

अगली बार यह धीमी गति से चलता है, संभवतः क्वेरी विश्लेषक का उपयोग करके कॉल करें और चयनित योजना प्राप्त करें - और यह जांचें कि यह कैसा दिखता है।

यदि यह है - तो प्रत्येक कॉल पर (एसपी के साथ) पर एसपी को फिर से सम्मिलित करने के लिए एक ऑप्टन में डालें।

+0

यह अच्छी तरह से यह हो सकता है पाया। मैंने संग्रहीत प्रक्रिया को प्रत्येक कॉल के साथ पुन: संकलित करने के लिए बदल दिया और ऐसा लगता है कि (अब के लिए!) चीजों को काफी हद तक बढ़ा दिया है। धन्यवाद! क्या पुनर्मूल्यांकन और खराब क्वेरी योजनाओं से बचने का कोई तरीका है? – Barguast

+0

नहीं। आप क्या कर सकते हैं संग्रहीत प्रक्रिया को डंप करें और गतिशील एसक्यूएल का उपयोग करें ... इसलिए क्वेरी योजना प्रत्येक कॉल को पुन: उत्पन्न करती है। संग्रहित प्रक्रियाओं के साथ यह एक ज्ञात मुद्दा है (सभी इसे समझ में नहीं आता है, केएम की तरह) - वे कभी-कभी वास्तव में खराब क्वेरी योजनाओं में बदल जाते हैं। – TomTom

2

पैरामीटर स्नीफिंग google it। क्वेरी पैरामीटर के आधार पर योजना लगता है की कोशिश कर रहा से एसक्यूएल सर्वर को रोकने के लिए इस है, जो स्थानीय चर करने के लिए "पुन: मैप" होगा इनपुट पैरामीटर का प्रयास करें:

ALTER PROCEDURE [dbo].[spGetPOIs] 
    @lat1 float, 
    @lon1 float, 
    @lat2 float, 
    @lon2 float, 
    @minLOD tinyint, 
    @maxLOD tinyint, 
    @exact bit 
AS 
BEGIN 
DECLARE @X_lat1 float, 
    @X_lon1 float, 
    @X_lat2 float, 
    @X_lon2 float, 
    @X_minLOD tinyint, 
    @X_maxLOD tinyint, 
    @X_exact bit 



    -- Create the query rectangle as a polygon 
    DECLARE @bounds geography; 
    SET @bounds = dbo.fnGetRectangleGeographyFromLatLons(@X_lat1, @X_lon1, @lX_at2, @X_lon2); 

    -- Perform the selection 
    if (@exact = 0) 
    BEGIN 
     SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID] 
     FROM [POIs] 
     WHERE 
      NOT ((@X_maxLOD [MaxLOD])) AND 
      (@bounds.Filter([Location]) = 1) 
    END 
    ELSE 
    BEGIN 
     SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID] 
     FROM [POIs] 
     WHERE 
      NOT ((@X_maxLOD [MaxLOD])) AND 
      (@bounds.STIntersects([Location]) = 1) 
    END 

END 
+0

मैंने पहले से ही कोशिश की, और ऐसा कोई फर्क नहीं पड़ता। मुझे इसे एक और जाना होगा। – Barguast

0

मैं एक ऐसी ही समस्या थी और यह सूचकांक संबंधित था।
उन्हें पुनर्निर्माण करने से एसपी को फिर से दौड़ने में मदद मिलती है।

मैं समाधान here

USE master; 
GO 

CREATE PROC DatabaseReIndex(@Database VARCHAR(100)) AS 
BEGIN 
    DECLARE @DbID SMALLINT=DB_ID(@Database)--Get Database ID 
    IF EXISTS(SELECT * FROM tempdb.sys.objects WHERE name='Indexes') 
    BEGIN --Delete Temp Table if exists, then create 
    DROP TABLE TempDb.dbo.Indexes 
    END 

CREATE TABLE TempDb.dbo.Indexes(IndexTempID INT IDENTITY(1,1),SchemaName NVARCHAR(128),TableName NVARCHAR(128),IndexName NVARCHAR(128),IndexFrag FLOAT) 
EXEC ('USE '[email protected]+'; 
INSERT INTO TempDb.dbo.Indexes(TableName,SchemaName,IndexName,IndexFrag) 
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,sch.name,ind.name IndexName,indexstats.avg_fragmentation_in_percent 
FROM sys.dm_db_index_physical_stats('[email protected]+', NULL, NULL, NULL, NULL) indexstats 
INNER JOIN sys.indexes ind ON ind.object_id = indexstats.object_id AND ind.index_id = indexstats.index_id 
INNER JOIN sys.objects obj on obj.object_id=indexstats.object_id 
INNER JOIN sys.schemas as sch ON sch.schema_id = obj.schema_id 
WHERE indexstats.avg_fragmentation_in_percent > 10 AND indexstats.index_type_desc<>''HEAP'' 
ORDER BY indexstats.avg_fragmentation_in_percent DESC')--Get index data and fragmentation, set the percentage as high or low as you need 

DECLARE @IndexTempID BIGINT=0,@SchemaName NVARCHAR(128),@TableName NVARCHAR(128),@IndexName NVARCHAR(128),@IndexFrag FLOAT 
SELECT * FROM TempDb.dbo.Indexes --View your results, comment out if not needed... 

-- Loop through the indexes 
WHILE @IndexTempID IS NOT NULL 
    BEGIN 
    SELECT @SchemaName=SchemaName,@TableName=TableName,@IndexName=IndexName,@IndexFrag=IndexFrag FROM TempDb.dbo.Indexes WHERE [email protected] 
    IF @IndexName IS NOT NULL AND @SchemaName IS NOT NULL AND @TableName IS NOT NULL 
    BEGIN 
     IF @IndexFrag<30. 
     BEGIN --Low fragmentation can use re-organise, set at 30 as per most articles 
     PRINT 'USE '[email protected]+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REORGANIZE' 
     EXEC('USE '[email protected]+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REORGANIZE') 
     END 
    ELSE 
     BEGIN --High fragmentation needs re-build 
     PRINT 'USE '[email protected]+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REBUILD' 
     EXEC('USE '[email protected]+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REBUILD') 
     END 
    END 

    SET @IndexTempID=(SELECT MIN(IndexTempID) FROM TempDb.dbo.Indexes WHERE IndexTempID>@IndexTempID) 
    END 
END 

DROP TABLE TempDb.dbo.Indexes 

GO 
संबंधित मुद्दे