从SQL Server DB获取记录时,存储过程花费太多时间

时间:2016-08-06 05:42:32

标签: sql sql-server

我想加快我的存储过程。在获取记录时,存储过程需要花费太多时间。

即。它将花费太多时间(超过1分钟)..

那么如何加快速度呢?

这是我的存储过程:

ALTER PROCEDURE [dbo].[usp_PostedAds_GetAllByCountryCityCategoryIdAdType]   
    (@countryId int,
     @cityId int, 
     @CategoryId int,
     @AdType int) 
AS
BEGIN
    DECLARE @ParentCatID int

    SET @ParentCatID = ISNULL((SELECT ParentID 
                               FROM Category 
                               WHERE ID = @CategoryId), 0)

    IF(@ParentCatID > 0)
    BEGIN 
        SELECT
            PostedAds.*,
            ISNULL((SELECT TOP 1 PostedAdsImages.AdsImage 
                    FROM PostedAdsImages 
                    WHERE PostedAdsImages.PostedAdsID = PostedAds.ID), 'noimage.jpg') AS AdsImage,
            (SELECT Name FROM dbo.Category WHERE id = PostedAds.CategoryID) as CategoryName,
            (SELECT ShowReply FROM dbo.Category WHERE id = PostedAds.CategoryID) as ShowReply,
            ISNULL((select mf.ID from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID where ms.ID=PostedAds.SubscriptionId),0) as FeatureId,
            isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') as FeatureTitle
            ,(select isnull(dbo.ConcatDynamicFields(PostedAds.Id),'')) as DynamicFields,
            isnull((select top 1 ul.IsLogin from UserLogin ul where ul.UserId=PostedAds.UserId order by ul.ID desc),0) as IsLoggedinUser
            ,isnull((select dbo.ConcatLocations1(postedAds.Id)),'') as location,
            (select Country_State.currency from Country_State where Country_State.ID=PostedAds.CountryID) as Currency   
            ,c.IsPriceAvailable
            from PostedAds join Category c on c.ID=PostedAds.CategoryID
            where PostedAds.Status=1 and PostedAds.CountryID=@countryId and 
            (PostedAds.CityId=@cityId or PostedAds.VisiblityRestriction=3)and PostedAds.CategoryID=@CategoryId and PostedAds.AdType=@AdType
            ORDER BY CASE 
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Premium Ads' THEN '1'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Urgent Ads' THEN '2'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = '' THEN '3'
                ELSE isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') 
                END 
                ,PostedAds.CreatedDate desc
            end
        else
            begin   
            if(@CategoryId>0)
                begin
                select PostedAds.*,isnull((select top 1 PostedAdsImages.AdsImage from PostedAdsImages where PostedAdsImages.PostedAdsID=PostedAds.ID),'noimage.jpg') as AdsImage
                ,(select Name from dbo.Category where id=PostedAds.CategoryID ) as CategoryName,(select ShowReply from dbo.Category where id=PostedAds.CategoryID ) as ShowReply,
                isnull((select mf.ID from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID where ms.ID=PostedAds.SubscriptionId),0) as FeatureId,
                isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') as FeatureTitle
                ,(select isnull(dbo.ConcatDynamicFields(PostedAds.Id),'')) as DynamicFields,
                isnull((select top 1 ul.IsLogin from UserLogin ul where ul.UserId=PostedAds.UserId order by ul.ID desc),0) as IsLoggedinUser
                ,isnull((select dbo.ConcatLocations1(postedAds.Id)),'') as location,
                (select Country_State.currency from Country_State where Country_State.ID=PostedAds.CountryID) as Currency   
                ,c.IsPriceAvailable
                from PostedAds join Category c on c.ID=PostedAds.CategoryID
                where PostedAds.Status=1 and PostedAds.CountryID=@countryId and 
                (PostedAds.CityId=@cityId or PostedAds.VisiblityRestriction=3) 
                and c.ParentID=@CategoryId 
                and PostedAds.AdType=@AdType
                ORDER BY CASE 
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Premium Ads' THEN '1'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Urgent Ads' THEN '2'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = '' THEN '3'
                ELSE isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') 
                END 
                ,PostedAds.CreatedDate desc
                End
            else
                Begin
                select PostedAds.*,isnull((select top 1 PostedAdsImages.AdsImage from PostedAdsImages where PostedAdsImages.PostedAdsID=PostedAds.ID),'noimage.jpg') as AdsImage
                ,(select Name from dbo.Category where id=PostedAds.CategoryID ) as CategoryName,(select ShowReply from dbo.Category where id=PostedAds.CategoryID ) as ShowReply,
                isnull((select mf.ID from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID where ms.ID=PostedAds.SubscriptionId),0) as FeatureId,
                isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') as FeatureTitle
                ,(select isnull(dbo.ConcatDynamicFields(PostedAds.Id),'')) as DynamicFields,
                isnull((select top 1 ul.IsLogin from UserLogin ul where ul.UserId=PostedAds.UserId order by ul.ID desc),0) as IsLoggedinUser
                ,isnull((select dbo.ConcatLocations1(postedAds.Id)),'') as location,
                (select Country_State.currency from Country_State where Country_State.ID=PostedAds.CountryID) as Currency   
                ,c.IsPriceAvailable
                from PostedAds join Category c on c.ID=PostedAds.CategoryID
                where PostedAds.Status=1 and PostedAds.CountryID=@countryId and 
                (PostedAds.CityId=@cityId or PostedAds.VisiblityRestriction=3)
                --and c.ID=@CategoryId 
                and PostedAds.AdType=@AdType
                ORDER BY CASE 
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Premium Ads' THEN '1'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = 'Urgent Ads' THEN '2'
                WHEN isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'')  = '' THEN '3'
                ELSE isnull((select mf.Title from MembershipSuscription ms left join dbo.MembershipPlan mp on mp.ID =ms.MembershipPlanID join MembershipFeature mf  on mf.ID =mp.FeatureID  where ms.ID=PostedAds.SubscriptionId),'') 
                END 
                ,PostedAds.CreatedDate desc
                End
            end     


end

这是我的表架构:

CREATE TABLE [dbo].[Category]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ParentID] [int] NOT NULL,
    [Name] [varchar](max) NULL,
    [CategoryImage] [varchar](max) NULL,
    [Active] [bit] NOT NULL CONSTRAINT [DF_Category_Active]  DEFAULT ((1)),
    [Offer_Label] [varchar](100) NULL,
    [Wanted_Label] [varchar](100) NULL,
    [seo_keywords] [varchar](255) NULL,
    [seo_description] [varchar](255) NULL,
    [IsProduct] [bit] NULL,
    [Order] [int] NULL DEFAULT ((0)),
    [IsPriceAvailable] [bit] NOT NULL DEFAULT ((1)),
    [ShowReply] [bit] NOT NULL DEFAULT ((1)),
    [AllowImages] [bit] NOT NULL DEFAULT ((1)),

    CONSTRAINT [PK_Category] 
       PRIMARY KEY CLUSTERED ([ID] ASC)
          WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

SET ANSI_PADDING OFF
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Country_State]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](200) NULL,
    [ParentID] [int] NULL,
    [HasState] [bit] NULL,
    [Currency] [varchar](50) NULL,
    [IsActive] [bit] NOT NULL CONSTRAINT [DF_Country_State_IsActive]  DEFAULT ((1)),
    [IsTopCountry] [bit] NULL CONSTRAINT [DF_Country_State_IsTopCountry]  DEFAULT ((0)),

    CONSTRAINT [PK_Country_State] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_PADDING OFF
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MembershipFeature]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Title] [nvarchar](255) NULL,
    [Type] [nvarchar](255) NULL,
    [Status] [bit] NULL,

    CONSTRAINT [PK_MembershipFeature] 
       PRIMARY KEY CLUSTERED ([ID] ASC)
          WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MembershipPlan]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [FeatureID] [int] NULL,
    [NumberOfAds] [int] NULL,
    [AdValidity] [int] NULL,
    [PlanValidity] [int] NULL CONSTRAINT [DF_MembershipPlan_PlanValidity]  DEFAULT ((0)),
    [Price] [decimal](18, 2) NULL,
    [Discount] [decimal](18, 2) NOT NULL,

    CONSTRAINT [PK_Plan_1] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MembershipSuscription]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [bigint] NOT NULL,
    [MembershipPlanID] [int] NOT NULL,
    [StartDate] [datetime] NULL CONSTRAINT [DF_MembershipSuscription_StartDate]  DEFAULT (getdate()),
    [EndDate] [datetime] NULL CONSTRAINT [DF_MembershipSuscription_EndDate]  DEFAULT (getdate()),
    [AmountPaid] [decimal](18, 2) NULL,
    [ServiceTax] [decimal](18, 2) NULL,
    [Status] [bit] NULL,
    [CreateDate] [datetime] NULL CONSTRAINT [DF_MembershipSuscription_CreateDate]  DEFAULT (getdate()),
    [AdRemaning] [int] NULL,

    CONSTRAINT [PK_MerchantMembershipSuscription] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[PostedAds]
(
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [UserId] [bigint] NOT NULL,
    [CategoryID] [int] NOT NULL,
    [Price] [decimal](18, 2) NULL,
    [Title] [nvarchar](max) NULL,
    [Description] [nvarchar](max) NULL,
    [MAPAddress] [nvarchar](max) NULL,
    [VisiblityRestriction] [int] NULL,
    [CountryID] [int] NOT NULL,
    [CityId] [int] NOT NULL,
    [Locality] [nvarchar](max) NULL,
    [Status] [int] NOT NULL CONSTRAINT [DF_PostedAds_Status]  DEFAULT ((0)),
    [Seo_keyword] [nvarchar](555) NULL,
    [Seo_description] [nvarchar](555) NULL,
    [AdType] [int] NULL,
    [PromotionType] [int] NOT NULL CONSTRAINT [DF_PostedAds_PromotionType]  DEFAULT ((0)),
    [SubscriptionId] [int] NULL CONSTRAINT [DF_PostedAds_SubscriptionId]  DEFAULT ((0)),
    [CreatedDate] [datetime] NULL CONSTRAINT [DF_PostedAds_CreatedDate]  DEFAULT (getdate()),

    CONSTRAINT [PK_PostedAds] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PostedAdsImages]
(
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [PostedAdsID] [bigint] NOT NULL,
    [AdsImage] [nvarchar](max) NULL,
    [ImageTitle] [nvarchar](500) NULL,
    [CreatedDate] [datetime] NULL CONSTRAINT [DF_PostedAdsImages_CreatedDate]  DEFAULT (getdate()),

    CONSTRAINT [PK_PostedAdsImages] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[UserLogin]
(
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [UserId] [bigint] NULL,
    [LoginDate] [date] NULL CONSTRAINT [DF_UserLogin_LoginDate]  DEFAULT (getdate()),
    [LoginTime] [varchar](50) NULL,
    [LogOutTime] [varchar](50) NULL,
    [IpAddress] [varchar](50) NULL,
    [IsLogin] [bit] NULL,

    CONSTRAINT [PK_UserLogin] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                 IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                 ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

如何加快这个存储过程?

有没有解决方案?

2 个答案:

答案 0 :(得分:0)

这与存储过程本身无关,而是与查询优化有关。一个起点可能是单独运行这些并使用DBMS的查询分析器(或计划输出)来查看是否有任何明显的热点可以通过调整查询或添加适当的索引来缓解。但是,在增加更多复杂性之前,将查询解释为其构成组件并将每个组件攻击到显示最佳性能的点通常会更有效率。

答案 1 :(得分:0)

您有from PostedAds join Category c on c.ID=PostedAds.CategoryID然后使用(SELECT Name FROM dbo.Category WHERE id = PostedAds.CategoryID) as CategoryName,为什么?您可以改用c.Name

我的建议:加入所有表格,然后选择您需要的内容,因为现在您的查询是混乱。下面的示例,重新制作您的第一个查询:

SELECT  pa.*,
        ISNULL(pai.AdsImage, 'noimage.jpg') AS AdsImage,
        c.Name as CategoryName,
        c.ShowReply as ShowReply,
        ISNULL(mf.ID,0) as FeatureId,
        ISNULL(mf.Title,'') as FeatureTitle,
        (select ISNULL(dbo.ConcatDynamicFields(pa.Id),'')) as DynamicFields,
        ISNULL(ul.IsLogin,0) as IsLoggedinUser,
        ISNULL((select dbo.ConcatLocations1(pa.Id)),'') as location,
        cs.currency as Currency,
        c.IsPriceAvailable
FROM PostedAds pa
INNER JOIN Category c 
    ON c.ID=pa.CategoryID
LEFT JOIN PostedAdsImages pai
    ON pai.PostedAdsID = pa.ID
LEFT JOIN MembershipSuscription ms  
    ON ms.ID=pa.SubscriptionId
LEFT JOIN dbo.MembershipPlan mp 
    ON mp.ID =ms.MembershipPlanID 
LEFT JOIN join MembershipFeature mf  
    ON mf.ID =mp.FeatureID
LEFT JOIN Country_State cs
    ON cs.ID=pa.CountryID
OUTER APPLY (
    select top 1 IsLogin 
    from UserLogin  
    where UserId=pa.UserId 
    order by ID desc) as ul
WHERE   pa.Status=1 and 
        pa.CountryID=@countryId and 
        (pa.CityId=@cityId or pa.VisiblityRestriction=3 )and 
        pa.CategoryID=@CategoryId and 
        pa.AdType=@AdType

ORDER BY CASE 
            WHEN ISNULL(mf.Title,'')  = 'Premium Ads' THEN '1'
            WHEN ISNULL(mf.Title,'')  = 'Urgent Ads' THEN '2'
            WHEN ISNULL(mf.Title,'')  = '' THEN '3'
            ELSE ISNULL(mf.Title,'') 
        END,
        pa.CreatedDate desc