【发布时间】:2023-03-18 19:54:01
【问题描述】:
最近将 SQL Server 2000 中的旧数据库迁移到 SQL Server 2005。
我做了以下事情:
- 在 SQL 2005 服务器上恢复 SQL 2000 数据库
- 将新数据库的兼容模式设置为 SQL 2005
- 在所有表上重建所有索引,更新所有统计信息
我偶然发现的一个问题是,在恢复的 SQL 2005 数据库中,一个查询似乎需要很长时间(实际上,像 5 分钟),而在原始 SQL 2000 数据库中则需要 3 秒。
这是具体的查询:
SELECT *
FROM Users
LEFT OUTER JOIN STAFF_Movement
ON Users.USERS_ID = STAFF_Movement.MOVEM_USERS_ID
WHERE
(
(
STAFF_Movement.MOVEM_Date = (
SELECT MAX(MOVEM_Date)
FROM STAFF_Movement sm
WHERE sm.MOVEM_USERS_ID = Users.USERS_ID
)
)
OR
(
STAFF_Movement.MOVEM_Date IS NULL
)
)
AND (Users.USERS_IsUser = 1)
ORDER BY Users.USERS_LastName, Users.USERS_FirstName
经过一番摸索和反复试验,我发现当我像在 SQL 2005 DB 上这样重写这个查询时,它再次执行得非常快,就像在 SQL 2000 上一样:
SELECT *
FROM Users u1
LEFT JOIN STAFF_Movement sm1 ON u1.USERS_ID = sm1.MOVEM_USERS_ID
AND
(
(
sm1.MOVEM_Date = (
SELECT MAX(sm.MOVEM_Date)
FROM STAFF_Movement sm
WHERE sm.MOVEM_USERS_ID = u1.USERS_ID
)
)
OR
(
sm1.MOVEM_Date IS NULL
)
)
WHERE
(u1.USERS_IsUser = 1)
ORDER BY u1.USERS_LastName, u1.USERS_FirstName
所以,基本上,我所做的是将条件从 where 子句中取出,并将其集成到 LEFT JOIN 逻辑中。
所以,虽然我自己找到了解决方案,但我仍然有以下问题没有得到解答:
- 为什么 SQL 2000 和 SQL 2005 在此查询方面存在差异?
- 为什么将过滤条件放在 JOIN 逻辑中而不是放在 WHERE 子句中时,性能会有所不同?
我必须补充一件重要的事情:这个数据库中的所有主键都是数据类型 GUID(不是我的设计,......我个人永远不会使用 GUID)。这会影响性能吗?
感谢您的任何回复。
马修
【问题讨论】:
-
两个版本的执行计划是什么样的?
标签: sql-server sql-server-2005 tsql sql-server-2000