检查 IS NOT NULL 很慢

Xav*_*ver 6 sql t-sql sql-server

我有以下问题:当我执行SQL语句时

\n\n
-- CTE\nWITH My_CTE AS\n(\n    SELECT [table_a].[ID]\n          ,[view_b].[val]\n    FROM [table_a]\n    LEFT JOIN [view_b] ON [a].[ID] = [b].[fk]\n)\n-- query with "is not null"\nSELECT * FROM My_CTE WHERE val IS NOT NULL\n
Run Code Online (Sandbox Code Playgroud)\n\n

执行需要8秒。在这种情况下,速度非常慢(没有 NULL 检查,查询返回 461 行,而使用 NULL 检查,查询返回 414 行,这并不算多)。

\n\n

我尝试通过使用表变量来提高速度:

\n\n
-- declare table variable\nDECLARE @test1 TABLE (ID int not null, val int null);\n\n-- CTE\nWITH My_CTE AS\n(\n    SELECT [table_a].[ID]\n          ,[view_b].[val]\n    FROM [table_a]\n    LEFT JOIN [view_b] ON [a].[ID] = [b].[fk]\n)\n-- Fill table variable\nINSERT INTO @test1 SELECT * FROM My_CTE\n\n-- query with "is not null"\nSELECT * FROM @test1 WHERE val IS NOT NULL\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里执行在不到 1 秒的时间内完成 - 这是预期的行为。

\n\n

但问题是我无法在视图 \xe2\x80\x93 中使用表变量,并且上面的 SQL 语句稍后应该集成到视图中。

\n\n

我的问题是:

\n\n
    \n
  • 原来的代码这么慢的原因是什么?
  • \n
  • 有没有什么方法可以在不使用表变量的情况下提高速度?
  • \n
\n

pap*_*zzo 2

您是否坚持使用该 CTE?

SELECT [table_a].[ID], [view_b].[val]
  FROM [table_a]
  JOIN [view_b] 
         ON [view_b].[fk] = [table_a].[ID] 
        AND [view_b].[val] IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

[view_b].[val] 上的索引可能会有所帮助