在存储过程中优化查询

时间:2019-02-10 11:42:09

标签: replace sql-server-2012 query-performance

此表包含五百万条记录:

CREATE TABLE [dbo].[T_PDF]
(
      [F_PRODUCT] [varchar](50) NOT NULL,
      [F_LANGUAGE] [varchar](2) NOT NULL,
      [F_PRODUCT_NAME] [nvarchar](2000) NULL,
      [F_FORMAT] [varchar](3) NOT NULL,
      [F_SUBFORMAT] NVARCHAR(10),
      [F_CUSTOM1] [nvarchar](4000) NULL,
      [F_CUSTOM2] [nvarchar](4000) NULL,
      [F_CUSTOM3] [nvarchar](4000) NULL,
      [F_CUSTOM4] [nvarchar](4000) NULL,
      [F_CUSTOM5] [nvarchar](4000) NULL,
      [F_COUNTER] [int] IDENTITY(1,1) NOT NULL,

      CONSTRAINT [PK_T_PDF] 
          PRIMARY KEY CLUSTERED ([F_PRODUCT] ASC,
                                 [F_LANGUAGE] ASC, 
                                 [F_FORMAT] ASC,
                                 [F_SUBFORMAT] ASC)
                  WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                        IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                        ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

此表的非聚集索引详细信息:

CREATE INDEX IX_PRODNAME ON T_PDF(F_PRODUCT_NAME)
CREATE INDEX IX_SUBFORMAT ON T_PDF(F_SUBFORMAT)

我的存储过程:

CREATE PROCEDURE [dbo].[TEST]
    @LANGUAGE  NVARCHAR(2),
    @SUBFORMAT   NVARCHAR(50),
    @PRODUCTNAME NVARCHAR(200),
AS
BEGIN
    SET NOCOUNT ON

    SELECT 
        TP.F_PRODUCT AS ID,
        TP.F_PRODUCT_NAME AS [NAME],
        TP.F_LANGUAGE AS LANGCODE,
        TP.F_FORMAT AS FMTCODE,
        TP.F_CUSTOM1 AS TN,
        TP.F_CUSTOM2 AS CP,
    FROM 
        T_PDF TP
    LEFT JOIN 
        V_PROD_ALIAS_SYN SYN ON SYN.F_PRODUCT = TP.F_PRODUCT
    WHERE
        TP.F_PRODUCT <> ''
        AND (@PRODUCTNAME IS NULL OR 
     REPLACE(REPLACE(REPLACE(REPLACE(TP.F_PRODUCT_NAME, '™', '|TM'), '®', '|TS'), '©', '|CP'), '°', '|DEG')
     LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PRODUCTNAME,'[','\['),'_','\_'),'™','|TM'),'®','|TS'),'©','|CP'),'°','|DEG') ESCAPE '\'

   OR REPLACE(TP.F_CUSTOM1,'^','') LIKE @PRODUCTNAME
   OR REPLACE(TP.F_CUSTOM2,'^','') LIKE @PRODUCTNAME
   OR REPLACE(TP.F_CUSTOM3,'^','') LIKE @PRODUCTNAME
   OR SYN.F_DATA LIKE @PRODUCTNAME)
   AND (@LANGUAGE IS NULL OR TP.F_LANGUAGE = @LANGUAGE OR @LANGUAGE = '-1')
  AND EXISTS (SELECT 1 FROM AllSubformats ASF WHERE ASF.Val = TP.F_SUBFORMAT)
END;

在上述过程中,搜索产品名称的三个OR条件:

OR REPLACE(TP.F_CUSTOM1,'^','') LIKE @PRODUCTNAME
OR REPLACE(TP.F_CUSTOM2,'^','') LIKE @PRODUCTNAME
OR REPLACE(TP.F_CUSTOM3,'^','') LIKE @PRODUCTNAME

当我传递或不传递@PRODUCTNAME作为输入参数时,表中要花更多的时间。

由于每个字段的大小为F_CUSTOM,因此我无法为以上三个NVARCHAR(4000)列创建索引。因此,我们如何为该列(F_CUSTOM1F_CUSTOM2F_CUSTOM3)或任何其他方法创建索引以改善此性能。

0 个答案:

没有答案