假设我现在有一套主细表 细表内数据量在800-1000万条纪录左右
现在我要修改其中1条纪录 使用以下两种方式
1. 使用条件直接update细表的纪录
2. 先根据主表内的条件将细表中所有符合主表条件的纪录全部删除 然后在将该符合主表条件的细表内容进行插入
请问 那种方式效率更高???
现在我要修改其中1条纪录 使用以下两种方式
1. 使用条件直接update细表的纪录
2. 先根据主表内的条件将细表中所有符合主表条件的纪录全部删除 然后在将该符合主表条件的细表内容进行插入
请问 那种方式效率更高???
因为update语句在sqlserver中本来主是一条delete语句加上一条insert语句.只不过你只写一条语句的时候,系统帮你分成了两条语句来执行.
比如说如果你更新主键,那么就是deferred update,相当于delete + insert
而如果你更新一个无索引字段,那么direct update
第二种方法不管怎么说都强制SQL Server去更新相关的索引,而第一种方法则如7楼所说,对索引的影响可大可小。更新数据量一大,或者使用时间一长之后,
第二种方法会明显导致索引碎片,从而降低速度的。
还记得instead of触发器中使用deleted表和inserted表吗?那就是为update操作准备的.如果要进行update操作,系统将进行delete操作和insert操作,涉及到创建insert表,接口数据向insert表传送,操作表中的数据向delete表中的转移,完整性约束检查,insert表中数据向操作表转移,delete表的删除这些步骤.
如果要进行delete操作加上insert操作,接口将传递两次数据
要比较这两组操作的效率,恐怕只能从这两种操作的效率去讨论.如果要说到11楼涉及的索引的问题,那只能问MS,它们在进行这两组操作的时候,分别是如何进行索引的了.
索引是不存在什么碎片的,因为它本身就是一种指针.
对表进行更新,或删除加插入,系统都会对盘区中数据页之间进行数据移动,行位置总是会发生变化的.所以操作效率与索引无关.
-------------------------------------------
建议仔细一下这个:
Microsoft SQL Server 2000 索引碎片整理最佳实践
http://www.dycar.net/blog/article.asp?id=158上面的内容翻译自MS官方的技术文档:
Microsoft SQL Server 2000 Index Defragmentation Best Practices
http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/ss2kidbp.mspx
deleted和inserted表可以认为是为了跟delete/insert的触发器里面的表命名兼容才这样做的,并不能证明真的这样做了
而且update 比 delete insert 产生的日志要小的多.
第一种.
第一种和第二种从索引维护的区别上来看,对于普通索引和非索引列,势必都引起更新, 对于主健如果你都更新,那么说明,你的设计有点问题.所以不考滤更新主健的情况.
第二种,先delete再insert有点脱了裤子..的感觉. 不要被触发器干扰
to 14楼朋友:
索引是不存在什么碎片的,因为它本身就是一种指针.
----------------------------
请问索引以是以什么方式存储的? 它不可能凭空出现, 既然SqlServer的索引以磁盘文件的形式出现,那么不可避免会有碎片产生.个人看法,仅供参考.
有些地方还是要用到楼主说的第二种情况
例:
权限模块中的 用户与角色 用名的角色是不固定的个数的,但是还是介意加一个标识列,select的时候加上where条件,
不过还是要看开发中具体情况而定
我的测试环境是
1.分别建立了2个数据库 (防止数据库有缓存问题的存在)
2.在2个数据库中分别建立了1个结构相同的表,字段数是30个。
3.做了一支程序,分别向两个表中插入300万条记录(查完耗时40分钟 晕)然后分别按照以上两种操作方式进行操作,影响的数据行数为70行,最后结果是:使用update:耗时1分14秒
使用delete+insert:耗时48.7秒最终从单次操作上看是使用第二种效率要高一些。至于楼上朋友所说的日志问题,理论上应该是第二种会高一些没有测试。