SQL对程序性能的影响
【先思考一个问题:聋子和瞎子在一起会有什么结果?】
昨天写程序,有个小模块是通过分析数十万条记录,与异构的数据表进行比对,找出符合条件的信息。
在第一条查询中,需要查询所有记录的一个字段,并提取该字段中的第5至第10个字符串,要与异构数据表比较的就是这个字串。在最初的版本中,对于性能并没有做更多的考虑,先从数据表中获取所有的记录组成的数据集,作为目标数据,再从异构数据表中获取数据集作为比对数据,然后在程序中经过至少两次遍历,筛选出想要的结果。在这个版本中,效率很低。比对数据基本上固定,千把条的样子,目标数据很多,而且会越来越多。但性能的瓶颈并不是出现在程序中多次的遍历,这些都在内存中进行,这点数据量和算法,对于目前的服务器来说真的是小菜一碟。经测试,虽然只有几十万行的记录,查询时间却需要5秒以上。
我原来的思路是,因为担心SQL的性能,把从字段中截取字符串的计算由SQL移至程序中进行,但实践证明,对于返回大量记录的SQL,其效率反而更低了。于是,改变思路,还是利用SQL进行筛选,并尽量减少数据量,有了类似下面这一行简单的查询:
select distinct substring([prodcode],5,10) pcode from [detail] order by pcode
在这段查询中,首先是利用substring函数,在sql中就返回了要想的字符串,注意这里substring函数和C#中的区别,它是从1开始索引的,而C#中则是从0开始(我在此走了弯路,如果聪明的你早就知道,请忽略)。然后是前面有个关键字distinct,用来消除重复的记录(这里存在大量的重复值)。实践证明,虽然增加了一个截取字符串的计算,但由于返回的记录大大减少,这种情况下,数据库服务器返回结果的时间提升到0秒,也就是说已经是毫秒级了,SSMS(=查询分析器)给忽略了。
众所周知,I/O对程序性能的影响相当大,在这个小小的实例中也能看出这一点。最开始,我想当然的以为把计算移到程序中去做,减轻一下数据库的负担,同时提高运算效率,却忽略了这个问题。当SQL返回了大量数据,这些数据要从一个地方移动到另一个地方,从目前的网络性能来看,耽误的时间绝对是不可以忽略的。
这个故事告诉我们,不能想当然,做程序如此,做任何事情都是如此。
PS
:最后不得不又要发个牢骚了,刚才提交的时候,差点又发生前功尽弃的事儿,正文文本框一片空白,和昨天提到的一样。也许是冥冥之中有神灵在帮我,在点提交按钮之前的那一瞬间,我打了个冷战,把这一堆文字复制到了记事本
相关文档:
----------Dbf 导入 Sql Server表----------
以下均以SQL2000、VFP6及以上的表为例
代码导入:查询分析器中执行如下语句(先选择对应的数据库)
-------------如果接受导入数据的SQL表已存在
--如果接受导入数据的SQL表已经存在
Insert Into 已经存在的SQL表名 Select * from openrowset('MSDASQL','Driver=Micros ......
from: http://www.javaeye.com/topic/498902?page=1
最近从朋友那看了一个某咨询公司给一家企业做的一个优化项目的总结报告书,其历时两个月,10万费用,4个人。
最终结果是性能和相应提升了30%,总共修改了3行代码和配置,共修改了3个单词,不到20个字母~~~~。
朋友总结了一句话,就是“代码质量越烂的项目 ......
其实在修改数据库名称之前,如果有用户连接到数据库的话会造成数据库重命名失败,可以先执行
select spid
from master.dbo.sysprocesses
where dbid=db_id('OldDbName')
结果集中显示的是当前连接到数据库OldDbName的连接
比如结果是
79
81
当然,实际值应该不是这两个
然后执行
kill 79
kill 81
关闭已建立 ......
因现在的工作需要,
我得从WinForm的平台,
转型到WebForm的页面。
有一年多没有接触SQL Server了,
虽然大学时有点基础,
但也忘记得差不多了。
因为Asp.net型的B/S网站和WinForm的还是有点不同,
现在工作起来不是那么得心应手。
温故而知新,
就把以前实习时做的的网站源代码拿出来看看。
因为要用到SQL 2005S ......