MSSQL网站制作之疾速删除反复纪录
这里我们讨论用binlog来实现闪回的方案。数据库中删除反复纪录一向是件挺烦人的事,自己搜集了Oracle跟SqlServer的疾速删除反复纪录的办法,供人人参考,但愿对人人有所匡助。SQLSERVER想必每位SQLSERVER开辟职员都有过相似的履历,在对数据库举行查询或统计的时分不时地会碰着因为表中存在反复的纪录而招致查询和统计了局禁绝确。办理该成绩的举措就是将这些反复的纪录删除,只保存个中的一条。
在SQLServer中除对具有十几笔记录的表举行野生删除外,完成删除反复纪录一样平常都是写一段代码,用游标的办法一行一行反省,删除反复的纪录。由于这类办法必要对全部表举行遍历,以是关于表中的纪录数不是很年夜的时分仍是可行的,假如一张表的数据到达上百万条,用游标的办法来删除几乎是个恶梦,由于它会实行相称长的一段工夫。
四板斧――轻松打消反复纪录
却不知在SQLServer中有一种更加复杂的办法,它不必要用游标,只需写一句复杂拔出语句就可以完成删除反复纪录的功效。为了能分明地表述,我们起首假定存在一个产物信息表Products,其表布局以下:
CREATETABLEProducts(
ProductIDint,
ProductNamenvarchar(40),
Unitchar(2),
UnitPricemoney
)
表中的数据如:
图表
中能够看出,产物Chang和Tofu的纪录在产物信息表中存在反复。如今要删除这些反复的纪录,只保存个中的一条。步骤以下:
第一板斧――创建一张具有不异布局的一时表
CREATETABLEProducts_temp(
ProductIDint,
ProductNamenvarchar(40),
Unitchar(2),
UnitPricemoney
)
第二板斧――为该表加上索引,并使其疏忽反复的值
办法是在企业办理器中找到下面创建的一时表Products_temp,单击鼠标右键,选择一切义务,选择办理索引,选择新建。如所示。
依照中圈出来的中央设置索引选项。
第三板斧――拷贝产物信息光临时表
insertintoProducts_tempSelect*fromProducts
此时SQLServer会前往以下提醒:
服务器:动静3604,级别16,形态1,行1
已疏忽反复的键。
它标明在产物信息一时表Products_temp中不会有反复的行呈现。
第四板斧――将新的数据导进原表
将原产物信息表Products清空,并将一时表Products_temp中数据导进,最初删除一时表Products_temp。
deleteProducts
insertintoProductsselect*fromProducts_temp
droptableProducts_temp
如许就完成了对表中反复纪录的删除。不管表有多年夜,它的实行速率都是相称快的,并且由于几近不必写语句,以是它也是很平安的。
小提醒:上述办法中删除反复纪录取决于创立独一索引时选择的字段,在实践的操纵过程当中读者务必起首确认创立的独一索引字段是不是准确,以避免将有效的数据删除。
ORACLE
在Oracle中,能够经由过程独一rowid完成删除反复纪录;还能够建一时表来完成...这个只提到个中的几种复杂有用的办法,但愿能够和人人分享(以表employee为例)。
SQL>descemployee
NameNull?Type
emp_idNUMBER(10)
emp_nameVARCHAR2(20)
salaryNUMBER(10,2)
能够经由过程上面的语句查询反复的纪录:
SQL>select*fromemployee;
EMP_IDEMP_NAMESALARY
1sunshine10000
1sunshine10000
2semon20000
2semon20000
3xyz30000
2semon20000
SQL>selectdistinct*fromemployee;
EMP_IDEMP_NAMESALARY
1sunshine10000
2semon20000
3xyz30000
SQL>select*fromemployeegroupbyemp_id,emp_name,salaryhavingcount(*)>1
EMP_IDEMP_NAMESALARY
1sunshine10000
2semon20000
SQL>select*fromemployeee1
whererowidin(selectmax(rowid)fromemployee2
wheree1.emp_id=e2.emp_idand
e1.emp_name=e2.emp_nameande1.salary=e2.salary);
EMP_IDEMP_NAMESALARY
1sunshine10000
3xyz30000
2semon20000
2.删除的几种办法:
(1)经由过程创建一时表来完成
SQL>createtabletemp_empas(selectdistinct*fromemployee)
SQL>truncatetableemployee;(清空employee表的数据)
SQL>insertintoemployeeselect*fromtemp_emp;(再将一时内外的内容插返来)
(2)经由过程独一rowid完成删除反复纪录.在Oracle中,每笔记录都有一个rowid,rowid在全部数据库中是独一的,rowid断定了每笔记录是在Oracle中的哪个数据文件、块、行上。在反复的纪录中,大概一切列的内容都不异,但rowid不会不异,以是只需断定出反复纪录中那些具有最年夜或最小rowid的就能够了,其他全体删除。
SQL>deletefromemployeee2whererowidnotin(
selectmax(e1.rowid)fromemployeee1where
e1.emp_id=e2.emp_idande1.emp_name=e2.emp_nameande1.salary=e2.salary);--这里用min(rowid)也能够。
SQL>deletefromemployeee2whererowid<(
selectmax(e1.rowid)fromemployeee1where
e1.emp_id=e2.emp_idande1.emp_name=e2.emp_nameande1.salary=e2.salary);
(3)也是经由过程rowid,但效力更高。
SQL>deletefromemployeewhererowidnotin(
selectmax(t1.rowid)fromemployeet1groupbyt1.emp_id,t1.emp_name,t1.salary);--这里用min(rowid)也能够。
EMP_IDEMP_NAMESALARY
1sunshine10000
3xyz30000
2semon20000
Memory所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在Mysql重新启动时丢失 从底层原理到表层引用,书籍多的很。个人认为没有什么那本书好?这样的说法。主要看和个人的学习方法是否适合。 SP4是一个累积性的ServicePack,包含自以前的ServicePack发布以来所有的修补程序(包括MS03-031安全公告)。 是否碎片会引发效率问题?这都是需要进一步探讨的东西。varbinary(max)代替image也让SQLServer的字段类型更加简洁统一。 groupby子句可以将查询结果分组,并返回行的汇总信息Oracle按照groupby子句中指定的表达式的值分组查询结果。 现在是在考虑:如果写到服务器端,我一下搞他个10个存储过程导过去,那久之服务器不就成垃圾箱了吗?即便优化了我的中间层. 我是新手,正在学习数据库和操作系统,深感理论的泛广,唯有一步一步来,但是又感觉时间不够,收集了很多资料却总是没能认真的看完,希望有一个讨论板块,大家共同解决,共同分享,共同努力 同样会为索引视图等应用带来麻烦。看看行级和事务级的快照数据放在tempdb中,就能感觉到目前架构的尴尬。 多加的系统视图和实时系统信息这些东西对DBA挑优非常有帮助,但是感觉粒度还是不太细。
页:
[1]