按照你的方法,record表中的id字段要全部查询一遍,也就是2W次查询,而每次查询,最坏
情况下需要与offline_record中的rec.id进行4W次比较,这又导致offline_record表的4W次
查询(取rec_id )。假设满足
a.* from record a where a.id not in(select b.rec_id from offline_record)
条件的记录一共有N条,那么,最坏情况下,该算法所做的查询次数为:
2W(取record.id)+2W*4W(每取一次record.id就要取一次offline_record.rec_id且offline_record的最后一条数据满足条件)+N(每
条满足条件的记录需要再在record中取该记录全部数据)
所做的比较次数为:
2W*4w
考虑最好情况下的效率,该算法所做的查询次数为:
2W(取record.id)+2W*1(每取一次record.id就要取一次offline_record.rec_id且offline_record的第一条数据满足条件)+N(N(每
条满足条件的记录需要再在record中取该记录全部数据)
所做的比较次数为:
2W*1
因此,该算法平均查询次数为:
2W+(4w*2w+1)*2w/2+N ->8*10^12
天文数字!这还不考虑将近4亿次的平均比较次数,所以你的执行效率当然低了
下面,我们对该算法来进行优化:
算法主要解决的问题是,取表record中id不等于offline_record.rec_id的数据。现假定id为record的主键(你的问题没有指明,但是你会看到无论id是否主键都不影响分析),设计算法如下:
1、取offline_record.rec_id的结果为集合,并对该集合进行排序,设最终生成的集合为A 。则,查询数据库4w次,生成集合的算法按照O(N*ln N)的效率来算平均情况下比较O(4W*ln 4w),约等于64W次,排序次数按照O(N*ln N)的效率来算平均情况下比较O(4W*ln 4w),约等于64W次。
2、顺序取record中的id与第一步生成的集合A进行比较,从而得出最终结果。该过程中由于record.id与A均为有序表,所以比较次数为2w次,查询次数为2w+N次。
如上算法,查询次数为 4W+2W+N=6W+N次,平均比较次数为 64W+64W+2W=130w次。
显而易见,该算法对原算法进行了最大的优化,大概将速度提高了10*8倍。
考虑到对数据库的查询时间远远大于排序比较时间,改进厚的算法在实际 *** 作中还会有更好的表现。
至于你对mysql查询语句的优化,则是治标不治本之举,虽然有用,但毕竟是微小量变,不足与影响全局,在一个坏的算法下,几乎不能提升性能。
首先,你现在写的这个sql是不能查询到你描述的结果的。
c表(xl_account),没看明白是干什么的的,先不管吧
a,b 两表通过id进行关联,应该是可以认为id相同则是同一(人)条记录
name不同应可以认为是做了修改,你用not in 则说明是不存在。假如,有2行记录,将名称互换,应该是两行都修改了,但是按照你现在的sql来看是应属于in的范围,not in 无法显示的,也就是查不出来。
所以,首先not in 改为 不等(!=), 才应该是你要找的数据。这样效率也是有所提高的。
若想要找到哪条记录修改,且要查询改前和改后的值,那么没有什么修改空间了,如果要查出哪条修改过,则有
select * from kd_user awhere not exists (
select 1 from lx_user b where a.id=b.id and a.name=b.name
)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)