更新:
我的不好......我在那些桌子上有一个主键......我的意思是目前没有进一步的索引 表。我们可能会在 看到性能之后的未来,因为我们对数据的过滤器太多了 检索数据上次我们运行数据库时索引没有显示出太大的改进 调谐。
我有数百万条记录的4个巨大的表格。现在存在经常调用的存储过程并更新这些表。这是场景 -
现在如果今天存在条目,我今天需要更新它,否则如果用户没有输入,我需要继续为用户插入条目。现在有两种方法可以执行这些,因为有一个proc可以执行此操作 -
第一种方式 -
IF EXISTS(TABLE1)
--UPDATE where condn
ELSE
--INSERT
IF EXISTS(TABLE2)
--UPDATE where condn
ELSE
--INSERT
IF EXISTS(TABLE3)
--UPDATE where condn
ELSE
--INSERT
IF EXISTS(TABLE4)
--UPDATE where condn
ELSE
--INSERT
第二种方式 -
DELETE from TABLE1 where condn
DELETE from TABLE2 where condn
DELETE from TABLE3 where condn
DELETE from TABLE4 where condn
INSERT TABLE1 ENTRY
INSERT TABLE2 ENTRY
INSERT TABLE3 ENTRY
INSERT TABLE4 ENTRY
现在第二种方式看起来更简单,但可能更耗时...我不确定哪种方式最好。任何人都可以帮助或指导我在这里..谢谢!
答案 0 :(得分:7)
如果您期望大多数插入,请尝试此
...
BEGIN TRY
INSERT table1
END TRY
BEGIN CATCH
IF ERROR_NUMBER = 2627
UPDATE table1
ELSE
--process real error
END CATCH
...
主要是更新...
...
BEGIN TRY
UPDATE table1 ... WHERE ...
IF @@ROWCOUNT = 0
INSERT Table1
END TRY
BEGIN CATCH
--optional. if someone manages to insert before here, do we update it? or just ignore it?
IF ERROR_NUMBER = 2627
UPDATE table1
ELSE
--process real error
END CATCH
...
EXISTS在高负载下并不足够。如果您要使用EXISTS扫描表,您也可以尝试INSERT。
编辑:我称之为JFDI模式......
答案 1 :(得分:2)
if-exists-then-update-else-insert 方法可能比 delete-insert 更多的代码,但是(取决于索引的数量和类型)在表格中定义)服务器的工作量少得多。
因此,除非您使用更新修改记录的每个索引字段,否则更长的方法就是效率更高。
编辑:您的问题更新说明目前除了主键(我假设是群集密钥)之外没有任何索引。所以相比之下:
当行已经存在时,它是1个聚簇索引查找(假设您通过PK查找记录)并且:
当行尚不存在时,它是1聚集索引搜索和:
存在的索引越多,删除/插入对已存在的行执行的情况就越糟糕。此外,由于可避免的写操作,它可能导致非聚集索引变得不必要地碎片化。
答案 2 :(得分:1)
试试这个:
UPDATE TABLE1 where condn
IF @@ROWCOUNT=0
INSERT TABLE1....
UPDATE TABLE2 where condn
IF @@ROWCOUNT=0
INSERT TABLE2....
UPDATE TABLE3 where condn
IF @@ROWCOUNT=0
INSERT TABLE3....
UPDATE TABLE4 where condn
IF @@ROWCOUNT=0
INSERT TABLE4....
不确定这是否有效(问题没有提供足够的信息):
UPDATE TABLE1 where condn
IF @@ROWCOUNT=0
BEGIN
INSERT TABLE1....
INSERT TABLE2....
INSERT TABLE3....
INSERT TABLE4....
END
ELSE
BEGIN
UPDATE TABLE2 where condn
UPDATE TABLE3 where condn
UPDATE TABLE4 where condn
END