原SQL:
DELETE
FROM [u]
WHERE dbId = 2
AND NOT EXISTS (
SELECT 1
FROM temp t
WHERE t.dbId = 2
AND t.tableId = 3
AND [u].[id] = CONVERT(BIGINT, t.pkId)
)
对于这种形式的sql, 有办法优化吗?这条语句要执行一个小时,而删除条件换成 Exists 执行则只需要几秒……
in 就更不消说了, 更慢……
网上找了一下, 据说什么 merge, except 可以代替, 但公司用的环境偏是 2005 , 难道就真的没有办法了吗?
------解决方案--------------------
not exists换成 left outer join应该会很快。
------解决方案--------------------
DELETE [u]
FROM [u] left join
temp t on t.dbId = 2 AND t.tableId = 3 AND [u].[id] = CONVERT(BIGINT, t.pkId)
WHERE [u].dbId = 2
,还有可以试试先在表设计里,把temp表的pkId改成BIGINT类型,减少类型转换消耗
------解决方案--------------------
既然 EXISTS 很快可以试试下面这样。
特别适合 temp 很大的时候,和 u 表 join 起来后中间表太大的情况。
INSERT INTO #T
SELECT id, 1 AS DeleteFlag
FROM [u]
WHERE dbId = 2;
UPDATE #T
SET DeleteFlag = 0
WHERE EXISTS (
SELECT 1
FROM temp t
WHERE t.dbId = 2
AND t.tableId = 3
AND #T.id = CONVERT(BIGINT, t.pkId)
);
DELETE [u]
FROM [u], #T
WHERE [u].dbId = 2
AND [u].id = #T.id
AND #T.DeleteFlag = 1
------解决方案--------------------
建议:
1.设定SQL维护计划,定期针对大表重整或重建索引.
2.确认数据库属性中自动更新统计信息已启用.
3.查看执行计划,看什么环结执行成本较高,针对性的解决.