确保代码中的数据类型与数据库中的列类型保持一致
确保您的应用程序各层数据类型保持一致是非常重要的。例如,如果一列的数据类型为NVARCHAR(50),那么,您应该在代码查询与存储过程中使用相同类型的局部变量。
同样,数据层中的ADO.NET代码也应该指定相同的数据类型与长度。为什么这很重要呢?因为如果数据类型与查询匹配,SQL Server需要先进行数据类型的隐式转换,以使它们能够匹配。
也有一些情况,即使为参照列设置了索引,SQL Server却不能使用此索引。因此,变量与列类型一致的情况下,您的查询可能会使用Index Scan而不是Index Seeking,这样需要执行的时间就更长了。
在批处理中进行大规模更新
开发人员有时需要对一张表中的一列或多列中的全部或大部分列进行数据修改。通常,对小表而言这并不是一个什么问题。
然而,如果表很大的话,您的更新语句将锁定整张表,使它无法使用,甚至都不能读取。更有甚者,对一张频繁变化的表进行更新可能使整个应用程序或网站瘫痪。有时,在极端情况下,一个大的、单个事务将导致事务日志急剧增长,并最终耗尽数据库服务器磁盘空间。
因此,好的策略是进行分批大规模更新,并结合频繁的事务日志备份。以我的经验看,最好一批10,000至50,000工作量。当您开始考虑应用批量处理时,确定阈值很困难,因为这取决于诸多因素比方说如何使I/O更快,如何使表高效利用等等。
您可以考虑一个准则。在ADO.NET中,典型的命令超时时间是30秒左右。当开始更新时,其他进程一直处于等待状态直到更新结束。因此如果期望更新时间超过20-25秒,您最好进行一个批处理更新。否则,将以应用程序超时而结束。
下面这段简单的代码展示了如何更新表中的一列,应用的批量大小为10,000:
WHILE ( 0 = 0 )
BEGIN
UPDATE TOP ( 10000 )
Person
SET Status = 2
WHERE Status = 1
IF @@ROWCOUNT = 0
BREAK
END
应用FOR-EACH存储过程
有些时候您可能需要对某一特定类型的所有对象执行相同的操作。例如,您可能需要对数据库中的所有表分配特定的权限。开发人员经常通过指针设置这样的任务,但是SQL Server中两个简单的存储过程可以更容易实现:sp_msForEachTable 与 sp_msForEachDB。
每个存储过程作为一个参数执行命令。在命令中,您把表名或数据库名作为一个问号标志占位符嵌入到参数中。命令运行时,SQL Server把问号标志替换为表名或数据库名,并执行。
例如,下面的代码在Server上除TempDB外,对每个数据库进行全备份:
EXEC sp_msforeachdb 'IF ''?'' <> ''tempdb'' BACKUP DATABASE ?
TO DISK=''c:\backups\?.bak'' WITH INIT'
这是另外一个如何应用这些存储过程的例子。下面的代码在禁用外键后,删除数据库所有表中的数据。当然了,当使用这些代码时,您需要谨慎的练习。
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable '
IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1
DELETE FROM ?
else
TRUNCATE TABLE ?
'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
建立数据库版本
对开发人员而言,如同对您的应用程序版本化一样,对数据库执行数字版本化是一个很好的方法。
执行版本化并不需要很大的工作量,您只需创建一个包含版本号列及时间戳列的版本表即可。当部署那些脚本时,您将更好的分配每个脚本集合的版本号,并对版本表进行更新,检查错误与数据库对比将变得更加容易。您甚至可以对脚本进行编号,这样一来如果数据库中建立的编号不比脚本中建立的编号高的话,脚本就不执行。样例数据库AdventureWorks中的AWBuildVersion就是一个很好的例子,可以看看。
尽量减少网络会话
这个技巧主要针对从数据库取数据的网络应用程序。缺乏经验的开发人员常常意识不到数据库调用是代价很高的操作。对于小应用程序而言,这不是什么大问题。但是,由于很多网站变得非常火爆导致数以千计的用户同时在线,那么您就有必要提前考虑它的可扩展性与网页加载时间的优化问题了。
我曾经看到过的网页有多达15个数据库调用,而大多数正在执行的存储过程就是为了返回单独的一行或一个值。需要牢记的是在SQL Server中一个单独的存储过程能够返回多个结果集。在一个存储过程中,您可以使用ADO.NET中的DataSet对象以及把DataTable对象组成一个集合。
确保您的应用程序各层数据类型保持一致是非常重要的。例如,如果一列的数据类型为NVARCHAR(50),那么,您应该在代码查询与存储过程中使用相同类型的局部变量。
同样,数据层中的ADO.NET代码也应该指定相同的数据类型与长度。为什么这很重要呢?因为如果数据类型与查询匹配,SQL Server需要先进行数据类型的隐式转换,以使它们能够匹配。
也有一些情况,即使为参照列设置了索引,SQL Server却不能使用此索引。因此,变量与列类型一致的情况下,您的查询可能会使用Index Scan而不是Index Seeking,这样需要执行的时间就更长了。
在批处理中进行大规模更新
开发人员有时需要对一张表中的一列或多列中的全部或大部分列进行数据修改。通常,对小表而言这并不是一个什么问题。
然而,如果表很大的话,您的更新语句将锁定整张表,使它无法使用,甚至都不能读取。更有甚者,对一张频繁变化的表进行更新可能使整个应用程序或网站瘫痪。有时,在极端情况下,一个大的、单个事务将导致事务日志急剧增长,并最终耗尽数据库服务器磁盘空间。
因此,好的策略是进行分批大规模更新,并结合频繁的事务日志备份。以我的经验看,最好一批10,000至50,000工作量。当您开始考虑应用批量处理时,确定阈值很困难,因为这取决于诸多因素比方说如何使I/O更快,如何使表高效利用等等。
您可以考虑一个准则。在ADO.NET中,典型的命令超时时间是30秒左右。当开始更新时,其他进程一直处于等待状态直到更新结束。因此如果期望更新时间超过20-25秒,您最好进行一个批处理更新。否则,将以应用程序超时而结束。
下面这段简单的代码展示了如何更新表中的一列,应用的批量大小为10,000:
WHILE ( 0 = 0 )
BEGIN
UPDATE TOP ( 10000 )
Person
SET Status = 2
WHERE Status = 1
IF @@ROWCOUNT = 0
BREAK
END
应用FOR-EACH存储过程
有些时候您可能需要对某一特定类型的所有对象执行相同的操作。例如,您可能需要对数据库中的所有表分配特定的权限。开发人员经常通过指针设置这样的任务,但是SQL Server中两个简单的存储过程可以更容易实现:sp_msForEachTable 与 sp_msForEachDB。
每个存储过程作为一个参数执行命令。在命令中,您把表名或数据库名作为一个问号标志占位符嵌入到参数中。命令运行时,SQL Server把问号标志替换为表名或数据库名,并执行。
例如,下面的代码在Server上除TempDB外,对每个数据库进行全备份:
EXEC sp_msforeachdb 'IF ''?'' <> ''tempdb'' BACKUP DATABASE ?
TO DISK=''c:\backups\?.bak'' WITH INIT'
这是另外一个如何应用这些存储过程的例子。下面的代码在禁用外键后,删除数据库所有表中的数据。当然了,当使用这些代码时,您需要谨慎的练习。
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable '
IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1
DELETE FROM ?
else
TRUNCATE TABLE ?
'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
建立数据库版本
对开发人员而言,如同对您的应用程序版本化一样,对数据库执行数字版本化是一个很好的方法。
执行版本化并不需要很大的工作量,您只需创建一个包含版本号列及时间戳列的版本表即可。当部署那些脚本时,您将更好的分配每个脚本集合的版本号,并对版本表进行更新,检查错误与数据库对比将变得更加容易。您甚至可以对脚本进行编号,这样一来如果数据库中建立的编号不比脚本中建立的编号高的话,脚本就不执行。样例数据库AdventureWorks中的AWBuildVersion就是一个很好的例子,可以看看。
尽量减少网络会话
这个技巧主要针对从数据库取数据的网络应用程序。缺乏经验的开发人员常常意识不到数据库调用是代价很高的操作。对于小应用程序而言,这不是什么大问题。但是,由于很多网站变得非常火爆导致数以千计的用户同时在线,那么您就有必要提前考虑它的可扩展性与网页加载时间的优化问题了。
我曾经看到过的网页有多达15个数据库调用,而大多数正在执行的存储过程就是为了返回单独的一行或一个值。需要牢记的是在SQL Server中一个单独的存储过程能够返回多个结果集。在一个存储过程中,您可以使用ADO.NET中的DataSet对象以及把DataTable对象组成一个集合。
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
2024年11月24日
2024年11月24日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]