SELECT 的行为变化
Behavior Changes on SELECT
我正在将 SQL Server 2008 数据库迁移到 SQL Server 2019,我使用了 Microsoft 数据迁移助手来查找任何行为更改、问题或语法错误。
我有一个 SELECT 给我进行迁移的兼容性错误:
Object uses the old style join syntax which can have poor performance at database compatibility level 90 and higher.
这是我认为错误的 SELECT:
SELECT
@Pro = CEILING((BaseDev * 100) / (ISNULL(BaseExe, 0) + ISNULL(BaseDev, 0)))
FROM
(SELECT SUM(Base) 'BaseDev'
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1
AND Fac = 'V' AND ISNULL(Pct, 0) <> 0) A,
(SELECT SUM(Base) 'BaseExe'
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V'
AND ISNULL(Pct, 0) = 0) B
SELECT @Pro = CEILING((A.BaseDev * 100) / (ISNULL(B.BaseExe, 0) + ISNULL(A.BaseDev, 0)))
FROM
(
SELECT SUM(Base) AS BaseDev
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V' AND ISNULL(Pct, 0) <> 0
) A
CROSS JOIN
(
SELECT SUM(Base) AS BaseExe
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V' AND ISNULL(Pct, 0) = 0
) B
我猜你可以用这个替换你的查询
您可以完全摆脱 JOIN
并使用条件聚合:
WITH CTE AS(
SELECT SUM(CASE WHEN Pct <> 0 THEN Base END) AS BaseDev,
SUM(CASE WHEN Pct = 0 OR Pct IS NULL THEN Base END) AS BaseExe
FROM dbo.Table1
WHERE Con = @Con
AND Lib <> 0
AND Tip = 1
AND Fac = 'V')
SELECT @Pro = CEILING((BaseDev * 100) / (ISNULL(BaseExe, 0) + ISNULL(BaseDev, 0)))
FROM CTE;
这 也应该 更高效,因为它会导致 table.
的单个 scan/seek
我正在将 SQL Server 2008 数据库迁移到 SQL Server 2019,我使用了 Microsoft 数据迁移助手来查找任何行为更改、问题或语法错误。
我有一个 SELECT 给我进行迁移的兼容性错误:
Object uses the old style join syntax which can have poor performance at database compatibility level 90 and higher.
这是我认为错误的 SELECT:
SELECT
@Pro = CEILING((BaseDev * 100) / (ISNULL(BaseExe, 0) + ISNULL(BaseDev, 0)))
FROM
(SELECT SUM(Base) 'BaseDev'
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1
AND Fac = 'V' AND ISNULL(Pct, 0) <> 0) A,
(SELECT SUM(Base) 'BaseExe'
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V'
AND ISNULL(Pct, 0) = 0) B
SELECT @Pro = CEILING((A.BaseDev * 100) / (ISNULL(B.BaseExe, 0) + ISNULL(A.BaseDev, 0)))
FROM
(
SELECT SUM(Base) AS BaseDev
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V' AND ISNULL(Pct, 0) <> 0
) A
CROSS JOIN
(
SELECT SUM(Base) AS BaseExe
FROM Table1
WHERE Con = @Con AND Lib <> 0 AND Tip = 1 AND Fac = 'V' AND ISNULL(Pct, 0) = 0
) B
我猜你可以用这个替换你的查询
您可以完全摆脱 JOIN
并使用条件聚合:
WITH CTE AS(
SELECT SUM(CASE WHEN Pct <> 0 THEN Base END) AS BaseDev,
SUM(CASE WHEN Pct = 0 OR Pct IS NULL THEN Base END) AS BaseExe
FROM dbo.Table1
WHERE Con = @Con
AND Lib <> 0
AND Tip = 1
AND Fac = 'V')
SELECT @Pro = CEILING((BaseDev * 100) / (ISNULL(BaseExe, 0) + ISNULL(BaseDev, 0)))
FROM CTE;
这 也应该 更高效,因为它会导致 table.
的单个 scan/seek