【问题标题】:SQL: 1=1 performance hitSQL:1=1 性能损失
【发布时间】:2018-08-22 17:46:12
【问题描述】:

我在我的应用程序中使用 SQL 查询和 sql server 来显示数据,它对性能产生了重大影响。 当查询被执行时,CPU 和 DTU 达到 100% 这是一个主要的性能问题。

查询:-

SELECT *
FROM   (SELECT Alls.*,
               ROW_NUMBER()
                 OVER (
                   ORDER BY Alls.col1 DESC) AS RowNum,
               COUNT(*)
                 OVER ()                    AS TotalCount
        FROM   tab1 AllS
               LEFT JOIN tab2 FF
                      ON Alls.col2 = FF.col2
        WHERE  ( ( ( @par1 IS NULL
                     AND 1 = 1 )
                    OR ( @par1 IS NOT NULL
                         AND '1' = fun1 (col3, ',', @par1, 'exact contains') ) )
                 AND ( ( @par2 IS NULL
                         AND 1 = 1 )
                        OR ( @par2 IS NOT NULL
                             AND ( Alls.col1 BETWEEN CONVERT(DATETIME, @par2) AND CONVERT(DATETIME, @par7) ) ) )
                 AND ( ( @par3 IS NULL
                         AND 1 = 1 )
                        OR ( @par3 IS NOT NULL
                             AND col4 IN (SELECT CONVERT(INT, Item)
                                          FROM   dbo.Split(@par3, ',')) ) )
                 AND ( ( ( @par4 IS NULL
                           AND col5 = NULL )
                          OR ( @par4 IS NOT NULL
                               AND col5 = @par4 ) )
                        OR ( ( @par5 IS NULL
                               AND col6 = NULL )
                              OR ( @par5 IS NOT NULL
                                   AND col6 = @par5 ) )
                        OR ( ( @par6 IS NULL
                               AND col7 = NULL )
                              OR ( @par6 IS NOT NULL
                                   AND col7 = @par6 ) )
                           AND ( ( @par8 IS NULL
                                   AND 1 = 1 )
                                  OR ( @par8 IS NOT NULL
                                       AND col8 IS NULL ) )
                           AND ( ( ( @par9 IS NULL
                                     AND 1 = 1 )
                                    OR ( @par9 IS NOT NULL
                                         AND col9 LIKE '%' + @par9 + '%' ) )
                                  OR ( ( @par9 IS NULL
                                         AND 1 = 1 )
                                        OR ( @par9 IS NOT NULL
                                             AND col8 = @par9 ) ) ) ) )
               AND col10 = 1
               AND col11 IS NULL) AS List
WHERE  RowNum BETWEEN @startRowIndex AND ( @startRowIndex + @pageSize ) - 1
ORDER  BY col1 DESC 

请建议如何优化查询。

这是架构:

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE tab1( [ID] [int] IDENTITY(1,1) NOT NULL, [col2] [uniqueidentifier] NOT NULL, [col5] [bit] NOT NULL, [col6] [bit] NOT NULL, [col7] [bit] NOT NULL, [col10] [bit] NOT NULL, [col1] [datetime] NOT NULL, [col4] [datetime] NOT NULL, [col3] [nvarchar](1000) NULL, [col11] [bit] NULL, [col8] [nvarchar](max) NULL, CONSTRAINT [PK_Alls] PRIMARY KEY CLUSTERED ( [col2] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ) 
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE tab2( [Id] [int] NULL, [col2] [varchar](40) NULL, [col9] [varchar](max) NULL, [col1] [datetime] NULL ) GO SET ANSI_PADDING OFF GO

【问题讨论】:

  • 您使用的是哪个 dbms?
  • 与任何性能问题一样 - 您需要告诉我们哪个数据库(我猜是 sql server 但您必须确认)显示的是架构、可用索引和查询计划会有所帮助。 'and 1=1' 不太可能是您的问题的原因。
  • 是的,它是一个 sql server
  • 不得不同意,去掉所有的1 = 1;这完全是在浪费编译器的时间。
  • col = null 会导致意想不到的结果,应该是col is null

标签: sql-server performance tsql query-optimization


【解决方案1】:

AND 1 = 1 在这里根本没用

@par4 IS NULL AND col5 = NULL - 不起作用

点击 1

AND '1' = fun1 (col3, ',', @par1, 'exact contains')

点击 2

AND col4 IN (SELECT CONVERT(INT, Item) FROM dbo.Split(@par3, ','))

点击 3

AND col9 LIKE '%' + @par9 + '%' )

点击 4

Alls.col1 BETWEEN CONVERT(DATETIME, @par2) AND CONVERT(DATETIME, @par7)

点击 5

... OR ... OR ... OR ... OR ... OR ...

还有分页本身。

请查看 Martin Smith 的链接。

【讨论】:

  • 我不确定您标记为 Hit 2 的内容是否真的很受欢迎;前提是 OP 有一个 good 分离器。如果是 TVF 或 CLR,应该不会太糟糕; CONVERT 在参数上(以及从它返回的结果),所以它不会导致它是不可SARGable;因为索引将在表上。当然,如果 OP 有一个 Multi-line Table Value Function,那将是一个巨大的打击,OP 应该考虑使用更好的解决方案。但是,这并不能解决该查询中的其余问题。 :)
  • 我没有看到这些函数的源代码,所以不能确定它们是否存在大问题。但是考虑到其余的代码,我很怀疑它们是否一切正常:)
  • 潜在命中 6:架构仅显示在第一个表(主键列)上创建的一个索引,OP 中没有任何内容表明任何其他列都存在索引。
【解决方案2】:

我已删除 1=1,并且我认为没有必要,因为我得到了相同的结果。 然后我尝试优化 OR OR 条件。 主要原因是JOIN。 现在,我正在寻找 LEFT JOIN

的替代方法

很高兴有更多的建议。

【讨论】:

    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多