??xml version="1.0" encoding="utf-8" standalone="yes"?>
as
set nocount on
create table TableSpace
(
TableName varchar(50),
RowsCount char(11),
Reserved varchar(18),
Data varchar(18),
Index_size varchar(18),
Unused varchar(18)
)
declare @sql varchar(500)
declare @TableName varchar(50)
declare Cursor1 Cursor
for
select name from sysobjects where xtype='U'
open Cursor1
fetch next from Cursor1 into @TableName
while @@fetch_status = 0
begin
set @sql = 'insert into TableSpace '
set @sql = @sql + ' exec sp_spaceused '''+ @TableName + ''' '
exec (@sql)
fetch next from Cursor1 into @TableName
end
close Cursor1
deallocate Cursor1
select tableName,rowscount from TableSpace where tableName<>'TableSpace'
order by rowscount desc
drop table TableSpace
go
exec ss
]]>
W一U方法:
思\是根据页号取Z部分数据Q比如取出前90条,然后取出?00条,然后比较取出两次l果的差集?br />
?0万条记录的情况下Q如果只?00(l果?0000条记录)Q大U需?分半钟。烦引徏得好的话Q?分钟左右?br />
//select * from //q一句是不能修改的了Q因为它是从l果中读取,所以必要?
//(select top @h_count (@filedlist) from @tableName .....) as big //取出W合条g的上限的记录
//where
//big.guid //q里是关键,Ҏ主键从下限结果中qo掉重复的记录Q只留下不同的数据,也就是求交集Q?br />
//not in
//(select top @l_count guid from @table .....)//下限
//order @orderby //原来的格式,q里只保留了orderby之后的,应该保留条g之后所有的Q包括gruopby什么的
函数cM如此Q?br />
public string MakeSqlPager(string sourceSql,int pageIndex)
{
//使用默认面大小
string orderbyStr=sourceSql.Substring(sourceSql.ToLower().IndexOf("order by"));
int index=sourceSql.ToLower().IndexOf("select");
string bigRes="("+ sourceSql.Insert(index+6," top "+((pageIndex+1)*_pageSize).ToString()+" ")+") as big";
string smallRes="("+ sourceSql.Insert(index+6," top "+(pageIndex*_pageSize).ToString()+" ")+")";
return "select * from "+bigRes+" where big.guid not in "+smallRes+" "+orderbyStr;
}
q种Ҏq可以改q,是W二ơ取qo时从W一个的l果里面qo?br />
W二U方法:
掐头dQ程序还没写
SELECT * FROM
(
SELECT TOP 100 * FROM
(
SELECT TOP 100000 * FROM pagetest ORDER BY regt ASC
) as a
ORDER BY regt desc
) as b
ORDER BY regt ASC
试了一下,大约用时?9U?br />
比较Q?br />
W一U方法的效率很低Q猜是因ؓ多次需要@环比较,旉复杂度要高一个等U。比如,q种Ҏ的响应时间和所取得的页h很大关系?br />
W二U方法还是可以接受的Q和号无关Q但是也需要两ơ比?br />
|上q有使用比较ID的方法的Q但是不是所有的表都有IDQ即使有Q也不一定是intcd的?br />
q有用存储过E创Z时表的,我还没有试效率如何
sqlserver里面没有rownum q个功能Q最新的2005beta2版本据说有了QOracle里面有)Q所以一ơ比较就能分늚法q真不好?
]]>
新徏作业Q?/span>
常规选项卡里,"名称"填写"定时备䆾数据?span>"Q?span>"启用"前面?span>"对勾"Q?span>"以本地服务器为目?span>"Q?/span>
"分类"选择"数据库服?span>"Q?/span>
步骤选项卡里Q新建步骤,步骤名:备䆾数据库;cdQ?span>Transact-SQL脚本(TSQL);
数据库:要备份的数据库;
命oQ?span>
declare @filename varchar (1000)
set @filename='E:\数据库备?span>\book'+convert(char(10),getdate(),112)
print @filename
BACKUP DATABASE [book] TO DISK = @filename WITH NOINIT , NOUNLOAD , NAME = N'备䆾', NOSKIP , STATS = 10,
NOFORMAT
调度选项卡里Q新度,名称:定时备䆾数据?span>; 调度cd:反复出现Q?/span>
通知选项卡里Q写?span>windows应用E序事g日至。当作业p|时?/span>
pagesizeQ?每页昄记录?br />cureentpageQ当前页?/p>
select * from ( select TOP pagesize * FROM ( SELECT TOP pagesize*cureentpage * from user_table ORDER BY id ASC ) as aSysTable ORDER BY id DESC ) as bSysTable ORDER BY id ASC
例子说明Q?/p>
假如数据库表如下Q?/p>
user_table:
id:主键Q自?br />username:字符
password:字符
假设?0条记录,每页昄10条记录,id ??0
现在按照id升序排列取出W三늚数据应该为:所取得记录的id 应该?21?0?/p>
q时该语句应该ؓQ?/p>
select * from ( select TOP 10 * FROM ( SELECT TOP 30 * from user_table ORDER BY id ASC ) as aSysTable ORDER BY id DESC ) as bSysTable ORDER BY id ASC
原理如下Q?/p>
先按照id从小到大升序取出30条记录(3*10Q?也就是:id ?1-30 之间的记?QSELECT TOP 30 * from user_table ORDER BY id ASCQ?/p>
然后按照ID降序排列q?0条记录,得到记录为id 在:?0?1
然后在这?0条记录中取出?0条记录:取得的记录ؓQid ?0-21之间。这是我们需要的数据Q但q时是按照降序排列的Q不W合要求?/p>
最后在重新排序得到最l我们需要的数据。id?1-30之间?/p>
下面的代码示例都以下面的表结构ؓ准:
Articles ?/td> | SQL Server cd | Oracle cd | |
PK | Id | int (自增) | number(9) (插入时在当前最大g?) |
Author | nvarchar(10) | nvarchar2(10) | |
Title | nvarchar(50) | nvarchar2(50) | |
PubTime | datetime | date |
SQL Server / Access {微软品中Q我们通常的自定义分页有两U思\Q?/p>
一U是?ASP.NET Forum Z表的、“时表”方法:卛_存储q程中徏立一个时表Q该临时表包含一个序号字D(1Q?Q?Q?...Q以及表的主键(其他能够唯一定一行记录的字段也是可以的)字段。存储过E可能如下:Q编?SS1Q?/font>
另一U可能更适合E序中“拼凑?SQL 语句Q用两次 TOP 命o取得我们所要的分页数据Q例如:Q编?SS2Q?/font>
q个的想法就是“掐头去䏀,q有不少分页的方法,q里׃一一列出了?/p>
对于 Oracle 数据库,有几处不同严重妨了上面几个Ҏ的实施,比如QOracle 不支?TOP 关键字:不过q个好像q不十分严重Q因为它提供?rownum q个隐式游标Q可以实C TOP cM的功能,如:
要写?/p>
rownum 是记录序P1Q?Q?...Q,但有一个比较麻烦的事情是:如果 SQL 语句中有 ORDER BY ... 排序的时候,rownum 居然是先“标号”后排序Q这Pq个序号如果不加处理是不合乎使用需求的?/p>
至于临时表,Oracle 的时表?SQL Server 的有很大不同Q我q没搞懂q个东西Q就不妄加揣了?/p>
国内|站中介l?Oracle 分页的资料很,我找C一个国外站点(www.faqts.comQ的一?FAQQ根据这文章的介绍Q可以如下分:Q编?Ora1Q?/font>
其中蓝色部分可以改ؓL的、需要的 SQL SELECT 语句Q这点倒是挺方便的?/p>
一、深入浅出理解烦引结?/b>
实际上,您可以把索引理解ZU特D的目录。微软的SQL SERVER提供了两U烦引:聚集索引Qclustered indexQ也U聚cȝ引、簇集烦引)和非聚集索引Qnonclustered indexQ也U非聚类索引、非集索引Q。下面,我们举例来说明一下聚集烦引和非聚集烦引的区别Q?br /> 其实Q我们的汉语字典的正文本w就是一个聚集烦引。比如,我们要查“安”字Q就会很自然地翻开字典的前几页Q因为“安”的拼音是“an”,而按照拼x序汉字的字典是以英文字母“a”开头ƈ以“z”结Q那么“安”字p然地排在字典的前部。如果您d了所有以“a”开头的部分仍然找不到这个字Q那么就说明您的字典中没有这个字Q同LQ如果查“张”字Q那您也会将您的字典d最后部分,因ؓ“张”的拼音是“zhang”。也是_字典的正文部分本w就是一个目录,您不需要再L其他目录来找到您需要找的内宏V我们把q种正文内容本n是一U按照一定规则排列的目录UCؓ“聚集烦引”?br /> 如果您认识某个字Q您可以快速地从自动中查到q个字。但您也可能会遇到您不认识的字,不知道它的发韻Iq时候,您就不能按照刚才的方法找到您要查的字Q而需要去Ҏ“偏旁部首”查到您要找的字Q然后根据这个字后的늠直接d某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序q不是真正的正文的排序方法,比如您查“张”字Q我们可以看到在查部首之后的字表中“张”的늠?72,字表中“张”的上面是“驰”字Q但늠却是63,“张”的下面是“徃”字Q页面是390c很昄Q这些字q不是真正的分别位于“张”字的上下方Q现在您看到的连l的“驰、张、徃”三字实际上是他们在非聚集索引中的排序Q是字典正文中的字在非聚集烦引中的映。我们可以通过q种方式来找到您所需要的字,但它需要两个过E,先找到目录中的结果,然后再翻到您所需要的늠。我们把q种目录Ua是目录,正文Ua是正文的排序方式UCؓ“非聚集索引”?br /> 通过以上例子Q我们可以理解到什么是“聚集烦引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解Q每个表只能有一个聚集烦引,因ؓ目录只能按照一U方法进行排序?br />
二、何时用聚集烦引或非聚集烦?/b>
下面的表ȝ了何时用聚集烦引或非聚集烦引(很重要)Q?/p>
动作描述
使用聚集索引
使用非聚集烦?/td>
列经常被分组排序
?/td>
?/td>
q回某范围内的数?/td>
?/td>
不应
一个或极少不同?/td>
不应
不应
数目的不同?/td>
?/td>
不应
大数目的不同?/td>
不应
?/td>
频繁更新的列
不应
?/td>
外键?/td>
?/td>
?/td>
主键?/td>
?/td>
?/td>
频繁修改索引?/td>
不应
?/td>
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如Q返回某范围内的数据一V比如您的某个表有一个时间列Q恰好您把聚合烦引徏立在了该列,q时您查?004q??日至2004q?0?日之间的全部数据Ӟq个速度将是很快的Q因为您的这本字典正文是按日期进行排序的Q聚cȝ引只需要找到要索的所有数据中的开头和l尾数据卛_Q而不像非聚集索引Q必d查到目录中查到每一Ҏ据对应的늠Q然后再Ҏ늠查到具体内容?br />
三、结合实际,谈烦引用的误区
理论的目的是应用。虽然我们刚才列Z何时应用聚集烦引或非聚集烦引,但在实践中以上规则却很容易被忽视或不能根据实际情况进行综合分析。下面我们将Ҏ在实践中遇到的实际问题来谈一下烦引用的误区Q以便于大家掌握索引建立的方法?br />
1、主键就是聚集烦?br /> q种xW者认为是极端错误的,是对聚集索引的一U浪贏V虽然SQL SERVER默认是在主键上徏立聚集烦引的?br /> 通常Q我们会在每个表中都建立一个ID列,以区分每条数据,q且q个ID列是自动增大的,步长一般ؓ1。我们的q个办公自动化的实例中的列Gid是如此。此Ӟ如果我们这个列设ؓ主键QSQL SERVER会将此列默认集烦引。这样做有好处,是可以让您的数据在数据库中按照IDq行物理排序Q但W者认样做意义不大?br /> 显而易见,聚集索引的优势是很明昄Q而每个表中只能有一个聚集烦引的规则Q这使得聚集索引变得更加珍贵?br /> 从我们前面谈到的聚集索引的定义我们可以看出,使用聚集索引的最大好处就是能够根据查询要求,q速羃查询范_避免全表扫描。在实际应用中,因ؓIDh自动生成的,我们q不知道每条记录的IDP所以我们很隑֜实践中用IDhq行查询。这׃让ID可个主键作集烦引成ZU资源浪贏V其ơ,让每个ID号都不同的字D作集烦引也不符合“大数目的不同值情况下不应建立聚合索引”规则;当然Q这U情况只是针对用L怿改记录内容,特别是烦引项的时候会负作用,但对于查询速度q没有媄响?br /> 在办公自动化pȝ中,无论是系l首|C的需要用L收的文g、会议还是用戯行文件查询等M情况下进行数据查询都M开字段的是“日期”还有用hw的“用户名”?br /> 通常Q办公自动化的首会昄每个用户未{收的文件或会议。虽然我们的where语句可以仅仅限制当前用户未{收的情况,但如果您的系l已建立了很长时_q且数据量很大,那么Q每ơ每个用h开首页的时候都q行一ơ全表扫描,q样做意义是不大的,l大多数的用?个月前的文g都已l浏览过了,q样做只能徒增数据库的开销而已。事实上Q我们完全可以让用户打开pȝ首页Ӟ数据库仅仅查询这个用戯3个月来未阅览的文Ӟ通过“日期”这个字D|限制表扫描,提高查询速度。如果您的办公自动化pȝ已经建立?q_那么您的首页昄速度理论上将是原来速度8倍,甚至更快?br /> 在这里之所以提到“理Z”三字,是因为如果您的聚集烦引还是盲目地建在IDq个主键上时Q您的查询速度是没有这么高的,即您在“日期”这个字D上建立的烦引(非聚合烦引)。下面我们就来看一下在1000万条数据量的情况下各U查询的速度表现Q?个月内的数据?5万条Q:
Q?Q仅在主键上建立聚集索引Qƈ且不划分旉D:
Select gid,fariqi,neibuyonghu,title from tgongwen
用时Q?28470毫秒Q即Q?28U)
Q?Q在主键上徏立聚集烦引,在fariq上徏立非聚集索引Q?/p>
select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi> dateadd(day,-90,getdate())
用时Q?3763毫秒Q?4U)
Q?Q将聚合索引建立在日期列QfariqiQ上Q?/p>
select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi> dateadd(day,-90,getdate())
用时Q?423毫秒Q?U)
虽然每条语句提取出来的都?5万条数据Q各U情늚差异却是巨大的,特别是将聚集索引建立在日期列时的差异。事实上Q如果您的数据库真的?000万容量的话,把主键徏立在ID列上Q就像以上的W??U情况,在网上的表现就是超ӞҎ无法显C。这也是我摒弃ID列作集烦引的一个最重要的因素。得Z上速度的方法是Q在各个select语句前加Q?/p>
declare @d datetime set @d=getdate()
q在select语句后加Q?/p>
select [语句执行p旉(毫秒)]=datediff(ms,@d,getdate())
2、只要徏立烦引就能显著提高查询速度
事实上,我们可以发现上面的例子中Q第2?条语句完全相同,且徏立烦引的字段也相同;不同的仅是前者在fariqi字段上徏立的是非聚合索引Q后者在此字D上建立的是聚合索引Q但查询速度却有着天壤之别。所以,q是在M字段上简单地建立索引p提高查询速度?br /> 从徏表的语句中,我们可以看到q个有着1000万数据的表中fariqi字段?003个不同记录。在此字D上建立聚合索引是再合适不q了。在现实中,我们每天都会发几个文Ӟq几个文件的发文日期q同,q完全符合徏立聚集烦引要求的Q“既不能l大多数都相同,又不能只有极数相同”的规则。由此看来,我们建立“适当”的聚合索引对于我们提高查询速度是非帔R要的?br />
3、把所有需要提高查询速度的字D都加进聚集索引Q以提高查询速度
上面已经谈到Q在q行数据查询旉M开字段的是“日期”还有用hw的“用户名”。既然这两个字段都是如此的重要,我们可以把他们合qv来,建立一个复合烦引(compound indexQ?br /> 很多为只要把M字段加进聚集索引Q就能提高查询速度Q也有h感到qhQ如果把复合的聚集烦引字D分开查询Q那么查询速度会减慢吗Q带着q个问题Q我们来看一下以下的查询速度Q结果集都是25万条数据Q:Q日期列fariqi首先排在复合聚集索引的v始列Q用户名neibuyonghu排在后列Q:
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>''2004-5-5''
查询速度Q?513毫秒
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>''2004-5-5'' and neibuyonghu=''办公?'
查询速度Q?516毫秒
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu=''办公?'
查询速度Q?0280毫秒
从以上试验中Q我们可以看到如果仅用聚集烦引的起始列作为查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一LQ甚x用上全部的复合烦引列q要略快Q在查询l果集数目一L情况下)Q而如果仅用复合聚集烦引的非v始列作ؓ查询条g的话Q这个烦引是不vM作用的。当Ӟ语句1?的查询速度一h因ؓ查询的条目数一P如果复合索引的所有列都用上,而且查询l果的话,q样׃形成“烦引覆盖”,因而性能可以辑ֈ最优。同Ӟ误住:无论您是否经怋用聚合烦引的其他列,但其前导列一定要是用最频繁的列?br />
四、其他书上没有的索引使用l验ȝ
1、用聚合索引比用不是聚合索引的主键速度?br /> 下面是实例语句:Q都是提?5万条数据Q?/p>
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
使用旉Q?326毫秒
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid<=250000
使用旉Q?470毫秒
q里Q用聚合索引比用不是聚合索引的主键速度快了q?/4?br />
2、用聚合索引比用一般的主键作order by旉度快,特别是在数据量情况?/p>
select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by fariqi
用时Q?2936
select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by gid
用时Q?8843
q里Q用聚合索引比用一般的主键作order byӞ速度快了3/10。事实上Q如果数据量很小的话Q用聚集索引作ؓ排序列要比用非聚集索引速度快得明显的多Q而数据量如果很大的话Q如10万以上,则二者的速度差别不明显?br />
3、用聚合烦引内的时间段Q搜索时间会按数据占整个数据表的癑ֈ比成比例减少Q而无合烦引用了多少个:
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-1-1''
用时Q?343毫秒Q提?00万条Q?
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-6-6''
用时Q?170毫秒Q提?0万条Q?/p>
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
用时Q?326毫秒Q和上句的结果一模一栗如果采集的数量一P那么用大于号和等于号是一LQ?/p>
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-1-1'' and fariqi<''2004-6-6''
用时Q?280毫秒
4、日期列不会因ؓ有分U的输入而减慢查询速度
下面的例子中Q共?00万条数据Q?004q??日以后的数据?0万条Q但只有两个不同的日期,日期_到日Q之前有数据50万条Q有5000个不同的日期Q日期精到U?/p>
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-1-1'' order by fariqi
用时Q?390毫秒
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi<''2004-1-1'' order by fariqi
用时Q?453毫秒
五、其他注意事?/b>
“水可蝲舟,亦可覆舟”,索引也一栗烦引有助于提高索性能Q但q多或不当的索引也会Dpȝ低效。因为用户在表中每加q一个烦引,数据库就要做更多的工作。过多的索引甚至会导致烦引碎片?br /> 所以说Q我们要建立一个“适当”的索引体系Q特别是对聚合烦引的创徏Q更应精益求_,以您的数据库能得到高性能的发挥?br /> 当然Q在实践中,作ؓ一个尽职的数据库管理员Q您q要多测试一些方案,扑և哪种Ҏ效率最高、最为有效?br />
可以通过如下Ҏ来优化查?:
1、把数据、日志、烦引放C同的I/O讑֤上,增加d速度Q以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量Q尺寸)大Q提高I/O重?
2、纵向、横向分割表Q减表的尺?sp_spaceuse)
3、升U硬?br />
4、根据查询条?建立索引,优化索引、优化访问方式,限制l果集的数据量。注意填充因子要适当Q最好是使用默认?Q。烦引应该尽量小Q用字节数的列徏索引好(参照索引的创建),不要Ҏ限的几个值的字段建单一索引如性别字段
5、提高网?
6、扩大服务器的内?Windows 2000和SQL server 2000能支?-8G的内存。配|虚拟内存:虚拟内存大小应基于计机上ƈ发运行的服务q行配置。运?Microsoft SQL Server? 2000 Ӟ可考虑虚拟内存大设|ؓ计算Z安装的物理内存的 1.5 倍。如果另外安装了全文索功能,q打运?Microsoft 搜烦服务以便执行全文索引和查询,可考虑Q将虚拟内存大小配置是计算Z安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配|选项配置为物理内存的 1.5 倍(虚拟内存大小讄的一半)?br />
7、增加服务器 CPU个数;但是必须明白q行处理串行处理更需要资源例如内存。用ƈ行还是串行程是MsSQL自动评估选择的。单个Q务分解成多个dQ就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行QSQL SERVERҎpȝ的负载情况决定最优的q行{Q复杂的需要消耗大量的CPU的查询最适合q行处理。但是更新操作Update,InsertQ?Deleteq不能ƈ行处理?br />
8、如果是使用likeq行查询的话Q简单的使用index是不行的Q但是全文烦引,耗空间?like 'a%' 使用索引 like '%a' 不用烦引用 like '%a%' 查询Ӟ查询耗时和字D值总长度成正比,所以不能用CHARcdQ而是VARCHAR。对于字D늚值很长的建全文烦引?br />
9、DB Server 和APPLication Server 分离QOLTP和OLAP分离
10、分布式分区视图可用于实现数据库服务器联合体。联合体是一l分开理的服务器Q但它们怺协作分担pȝ的处理负荗这U通过分区数据形成数据库服务器联合体的机制能够扩大一l服务器Q以支持大型的多?Web 站点的处理需要。有x多信息,参见设计联合数据库服务器。(参照SQL帮助文g'分区视图'Q?br />
a、在实现分区视图之前Q必d水^分区?br />
b、在创徏成员表后Q在每个成员服务器上定义一个分布式分区视图Qƈ且每个视囑օ有相同的名称。这P引用分布式分囑的查询可以在M一个成员服务器上运行。系l操作如同每个成员服务器上都有一个原始表的复本一P但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的?br />
11、重建烦?DBCC REINDEX ,DBCC INDEXDEFRAG,收羃数据和日?DBCC SHRINKDB,DBCC SHRINKFILE. 讄自动收羃日志.对于大的数据库不要设|数据库自动增长Q它会降低服务器的性能。在T-sql的写法上有很大的讲究Q下面列出常见的要点Q首先,DBMS处理查询计划的过E是q样的:
1?查询语句的词法、语法检?br />
2?语句提交给DBMS的查询优化器
3?优化器做代数优化和存取\径的优化
4?由预~译模块生成查询规划
5?然后在合适的旉提交l系l处理执?br />
6?最后将执行l果q回l用户其ơ,看一下SQL SERVER的数据存攄l构Q一个页面的大小?K(8060)字节Q?个页面ؓ一个盘区,按照B树存放?br />
12、Commit和rollback的区?Rollback:回滚所有的事物?Commit:提交当前的事? 没有必要在动态SQL里写事物Q如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过E?br />
13、在查询Select语句中用Where字句限制q回的行?避免表扫?如果q回不必要的数据Q浪费了服务器的I/O资源Q加重了|络的负担降低性能。如果表很大Q在表扫描的期间表锁住Q禁止其他的联接讉K?后果严重?br />
14、SQL的注释申明对执行没有M影响
15、尽可能不用光标,它占用大量的资源。如果需要row-by-row地执行,量采用非光标技?如:在客L循环Q用临时表,Table变量Q用子查询,用Case语句{等。游标可以按照它所支持的提取选项q行分类Q?只进 必须按照从第一行到最后一行的序提取行。FETCH NEXT 是唯一允许的提取操?也是默认方式。可滚动性可以在游标中Q何地斚w机提取Q意行。游标的技术在SQL2000下变得功能很强大Q他的目的是支持循环。有四个q发选项 READ_ONLYQ不允许通过游标定位更新(Update)Q且在组成结果集的行中没有锁?OPTIMISTIC WITH valueS:乐观q发控制是事务控制理论的一个标准部分。乐观ƈ发控制用于这L情ŞQ即在打开游标及更新行的间隔中Q只有很的Z让第二个用户更新某一行。当某个游标以此选项打开Ӟ没有锁控制其中的行,q将有助于最大化其处理能力。如果用戯图修Ҏ一行,则此行的当前g与最后一ơ提取此行时获取的D行比较。如果Q何值发生改变,则服务器׃知道其他人已更新了此行,q会q回一个错误。如果值是一LQ服务器执行修攏V选择q个q发选项OPTIMISTIC WITH ROW VERSIONING:此乐观ƈ发控刉项Z行版本控制。用行版本控制Q其中的表必d有某U版本标识符Q服务器可用它来定该行在读入游标后是否有所更改。在 SQL Server 中,q个性能?timestamp 数据cd提供Q它是一个二q制数字Q表C数据库中更改的相对序。每个数据库都有一个全局当前旉戛_|@@DBTS。每ơ以M方式更改带有 timestamp 列的行时QSQL Server 先在旉戛_中存储当前的 @@DBTS |然后增加 @@DBTS 的倹{如果某 个表h timestamp 列,则时间戳会被记到行。服务器可以比较某行的当前旉戛_和上次提取时所存储的时间戳|从而确定该行是否已更新。服务器不必比较所有列的|只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观ƈ发,则游标默认ؓZ数值的乐观q发控制?SCROLL LOCKS q个选项实现悲观q发控制。在悲观q发控制中,在把数据库的行读入游标结果集Ӟ应用E序试N定数据库行。在使用服务器游标时Q将行读入游标时会在其上攄一个更新锁。如果在事务内打开游标Q则该事务更新锁一直保持到事务被提交或回滚Q当提取下一行时Q将除去游标锁。如果在事务外打开游标Q则提取下一行时Q锁p丢弃。因此,每当用户需要完全的悲观q发控制Ӟ游标都应在事务内打开。更新锁阻止Q何其它Q务获取更新锁或排它锁Q从而阻止其它Q务更新该行。然而,更新锁ƈ不阻止共享锁Q所以它不会L其它dd行,除非W二个Q务也在要求带更新锁的d。滚动锁Ҏ在游标定义的 Select 语句中指定的锁提C,q些游标q发选项可以生成滚动锁。滚动锁在提取时在每行上获取Qƈ保持Cơ提取或者游标关闭,以先发生者ؓ准。下ơ提取时Q服务器为新提取中的行获取滚动锁Qƈ释放上次提取中行的滚动锁。滚动锁独立于事务锁Qƈ可以保持C个提交或回滚操作之后。如果提交时关闭游标的选项为关Q则 COMMIT 语句q不关闭M打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔R所获取滚动锁的cd取决于游标ƈ发选项和游?Select 语句中的锁提C。锁提示 只读 乐观数?乐观行版本控?锁定无提C?未锁?未锁?未锁?更新 NOLOCK 未锁?未锁定未锁定 未锁?HOLDLOCK ׃n ׃n ׃n 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁?未锁定更新其?未锁?未锁?未锁?更新 *指定 NOLOCK 提示指定了该提示的表在游标内是只ȝ?br />
16、用Profiler来跟t查询,得到查询所需的时_扑ևSQL的问题所?用烦引优化器优化索引
17、注意UNion和UNion all 的区别。UNION all?br />
18、注意用DISTINCTQ在没有必要时不要用Q它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的
19、查询时不要q回不需要的行、列
20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源出限制Ӟ服务器自动取消查?在查询之前就扼杀掉?SET LOCKTIME讄锁的旉
21、用select top 100 / 10 Percent 来限制用戯回的行数或者SET ROWCOUNT来限制操作的?br />
22、在SQL2000以前Q一般不要用如下的字? "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'"Q因Z们不走烦引全是表扫描。也不要在Where字句中的列名加函敎ͼ如ConvertQsubstring{?如果必须用函数的时候,创徏计算列再创徏索引来替?q可以变通写法:Where SUBSTRING(firstname,1,1) = 'm'改ؓWhere firstname like 'm%'Q烦引扫描)Q一定要函数和列名分开。ƈ且烦引不能徏得太多和太大。NOT IN会多ơ扫描表Q用EXISTS、NOT EXISTS QIN , LEFT OUTER JOIN 来替代,特别是左q接,而Exists比IN更快Q最慢的是NOT操作.如果列的值含有空Q以前它的烦引不起作用,现在2000的优化器能够处理了。相同的是IS NULLQ?NOT", "NOT EXISTS", "NOT IN"能优化她Q?<>"{还是不能优化,用不到烦引?br />
23、用Query AnalyzerQ查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重Ҏq些慢的地方?br />
24、如果用了IN或者OR{时发现查询没有走烦引,使用昄x指定索引Q?Select * FROM PersonMember (INDEX = IX_Title) Where processid IN ('?Q??)
25、将需要查询的l果预先计算好放在表中,查询的时候再Select。这在SQL7.0以前是最重要的手Dc例如医院的住院费计?br />
26、MIN() ?MAX()能用到合适的索引?br />
27、数据库有一个原则是代码L据越q越好,所以优先选择Default,依次为Rules,Triggers, ConstraintQ约束如外健dCheckUNIQUE…?数据cd的最大长度等{都是约束),Procedure.q样不仅l护工作,~写E序质量高,q且执行的速度快?br />
28、如果要插入大的二进制值到Image列,使用存储q程Q千万不要用内嵌Insert来插?不知JAVA是否)。因样应用程序首先将二进制D{换成字符Ԍ寸是它的两倍)Q服务器受到字符后又他转换成二q制?存储q程没有这些动? ҎQCreate procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过E传入二q制参数Q这样处理速度明显改善?br />
29、Between在某些时候比IN 速度更快,Between能够更快地根据烦引找到范围。用查询优化器可见到差别?select * from chineseresume where title in ('?,'?) Select * from chineseresume where between '? and '? 是一L。由于in会在比较多次Q所以有时会慢些?br />
30、在必要是对全局或者局部时表创徏索引Q有时能够提高速度Q但不是一定会q样Q因为烦引也耗费大量的资源。他的创建同是实际表一栗?br />
31、不要徏没有作用的事物例如生报表时Q浪费资源。只有在必要使用事物时用它?br />
32、用OR的字句可以分解成多个查询Qƈ且通过UNION q接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合烦引,用UNION all执行的效率更?多个OR的字句没有用到烦引,改写成UNION的Ş式再试图与烦引匹配。一个关键的问题是否用到索引?br />
33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻扑֎始资料的隑ֺ。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时Q不要用指向多个表的视图,直接从表索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到q扰.Z加快视图的查询,MsSQL增加了视囄引的功能?br />
34、没有必要时不要用DISTINCT和ORDER BYQ这些动作可以改在客L执行。它们增加了额外的开销。这同UNION 和UNION ALL一L道理?br />
select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345',
'JCNAD00333138','JCNAD00303570','JCNAD00303569',
'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',
'JCNAD00254567','JCNAD00254585','JCNAD00254608',
'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',
'JCNAD00279196','JCNAD00268613') order by postdate desc
35、在IN后面值的列表中,出现最频繁的值放在最前面Q出现得最的攑֜最后面Q减判断的ơ数?br />
36、当用Select INTOӞ它会锁住pȝ?sysobjectsQsysindexes{等)Q阻塞其他的q接的存取。创Z时表时用昄x语句Q而不?select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中Select * from sysobjects可以看到 Select INTO 会锁住系l表QCreate table 也会锁系l表(不管是时表q是pȝ?。所以千万不要在事物内用它Q!Q这L话如果是l常要用的时表请用实表,或者时表变量?br />
37、一般在GROUP BY 个HAVING字句之前p剔除多余的行Q所以尽量不要用它们来做剔除行的工作。他们的执行序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行QHaving字句用来剔除多余的分l。这样Group By 个Having的开销,查询?对于大的数据行进行分l和Having十分消耗资源。如果Group BY的目的不包括计算Q只是分l,那么用Distinct更快
38、一ơ更新多条记录比分多ơ更新每ơ一条快,是说批处理?br />
39、少用时表Q尽量用l果集和TablecL的变量来代替它,Table cd的变量比临时表好
40、在SQL2000下,计算字段是可以烦引的Q需要满的条g如下Q?br />
a、计字D늚表达是确定的
b、不能用在TEXT,NtextQImage数据cd
c、必配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …?
41、尽量将数据的处理工作放在服务器上,减少|络的开销Q如使用存储q程。存储过E是~译好、优化过、ƈ且被l织C个执行规划里、且存储在数据库中的SQL语句Q是控制语a的集合,速度当然快。反复执行的动态SQL,可以使用临时存储q程Q该q程Q时表Q被攑֜Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不这个工作放在其他的层上而增加网l的开销。SQL2000支持UDFs,现在支持复杂的数学计,函数的返回g要太大,q样的开销很大。用戯定义函数象光标一h行的消耗大量的资源Q如果返回大的结果采用存储过E?br />
42、不要在一句话里再三的使用相同的函敎ͼ费资源,结果放在变量里再调用更?br />
43、Select COUNT(*)的效率教低,量变通他的写法,而EXISTS?同时h意区别: select count(Field of null) from Table ?select count(Field of NOT null) from Table 的返回值是不同的!Q!
44、当服务器的内存够多Ӟ配制U程数量 = 最大连接数+5Q这栯发挥最大的效率Q否则?配制U程数量<最大连接数启用SQL SERVER的线E池来解?如果q是数量 = 最大连接数+5Q严重的损害服务器的性能?br />
45、按照一定的ơ序来访问你的表。如果你先锁住表AQ再锁住表BQ那么在所有的存储q程中都要按照这个顺序来锁定它们。如果你Q不l意的)某个存储q程中先锁定表BQ再锁定表AQ这可能׃D一个死锁。如果锁定顺序没有被预先详细的设计好Q死锁很难被发现
46、通过SQL Server Performance Monitor监视相应g的负?Memory: Page Faults / sec计数器如果该值偶走高,表明当时有线E竞争内存。如果持l很高,则内存可能是瓉?br /> Process:
1? DPC Time 指在范例间隔期间处理器用在缓延程序调?DPC)接收和提供服务的癑ֈ比?DPC 正在q行的ؓ比标准间隔优先权低的间隔)?׃ DPC 是以Ҏ模式执行的,DPC 旉的百分比为特权时间百分比的一部分。这些时间单独计ƈ且不属于间隔计算L的一?分。这个L昄了作为实例时间百分比的^均忙时?br />
2?Processor Time计数器 如果该参数值持l超q?5%Q表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器?br />
3? Privileged Time 指非闲置处理器时间用于特权模式的癑ֈ比?Ҏ模式是ؓ操作pȝlg和操U늡仉动程序而设计的一U处理模式。它允许直接讉Kg和所有内存。另一U模式ؓ用户模式Q它是一Uؓ应用E序、环境分pȝ和整数分pȝ设计的一U有限处理模式。操作系l将应用E序U程转换成特权模式以讉K操作pȝ服务)。特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备生的大数量的间隔而引L。这个计数器^均忙时作为样本时间的一部分昄?br />
4? User Time表示耗费CPU的数据库操作Q如排序Q执行aggregate functions{。如果该值很高,可考虑增加索引Q尽量用简单的表联接,水^分割大表格等Ҏ来降低该倹{?Physical Disk: Curretn Disk Queue Length计数器该值应不超q磁盘数?.5~2倍。要提高性能Q可增加盘?SQLServer:Cache Hit Ratio计数器该D高越好。如果持l低?0%Q应考虑增加内存?注意该参数值是从SQL Server启动后,׃直篏加记敎ͼ所以运行经q一D|间后Q该值将不能反映pȝ当前倹{?br />
47、分析select emp_name form employee where salary > 3000 在此语句中若salary是Floatcd的,则优化器对其q行优化为Convert(float,3000)Q因?000是个整数Q我们应在编E时使用3000.0而不要等q行时让DBMSq行转化。同样字W和整型数据的{换?br />
48、查询的兌同写的顺?br />
select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' QA = B ,B = 'L'Q?br />
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' QA = B ,B = 'L'Q?A = 'L'Q?br />
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' QB = 'L'Q?A = 'L'Q?br />
49?br />
(1)IF 没有输入负责Z?THEN code1=0 code2=9999 ELSE code1=code2=负责Z?END IF 执行SQL语句? Select 负责人名 FROM P2000 Where 负责Z?gt;=:code1 AND负责Z?<=:code2
(2)IF 没有输入负责Z?THEN Select 负责人名 FROM P2000 ELSE code= 负责Z?Select 负责Z?FROM P2000 Where 负责Z?:code END IF W一U方法只用了一条SQL语句,W二U方法用了两条SQL语句。在没有输入负责Z码时,W二U方法显然比W一U方法执行效率高,因ؓ它没有限制条? 在输入了负责Z码时,W二U方法仍然比W一U方法效率高,不仅是少了一个限制条?q因相等q算是最快的查询q算。我们写E序不要怕麻?br />
50、关于JOBCN现在查询分页的新ҎQ如下)Q用性能优化器分析性能的瓶颈,如果在I/O或者网l的速度上,如下的方法优化切实有效,如果在CPU或者内存上Q用现在的方法更好。请区分如下的方法,说明索引小好?br />
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by ReferenceID
select * from @local_variable where Fid > 40 and fid <= 60
end ?br />
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from @local_variable where Fid > 40 and fid <= 60
end 的不?br />
begin
create table #temp (FID int identity(1,1),ReferenceID varchar(20))
insert into #temp (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from #temp where Fid > 40 and fid <= 60 drop table #temp
end
另附Q存储过E编写经验和优化措施 FromQ网|学网
一、适合读者对象:数据库开发程序员Q数据库的数据量很多Q涉及到对SPQ存储过E)的优化的目开发h员,Ҏ据库有浓厚兴的人?
二、介l:在数据库的开发过E中Q经怼遇到复杂的业务逻辑和对数据库的操作Q这个时候就会用SP来封装数据库操作。如果项目的SP较多Q书写又没有一定的规范Q将会媄响以后的pȝl护困难和大SP逻辑的难以理解,另外如果数据库的数据量大或者项目对SP的性能要求很,׃遇到优化的问题,否则速度有可能很慢,l过亲nl验Q一个经q优化过的SP要比一个性能差的SP的效率甚至高几百倍?
三、内容:
1、开发h员如果用到其他库的Table或ViewQ务必在当前库中建立View来实现跨库操作,最好不要直接用“databse.dbo.table_name”,因ؓsp_depends不能昄SP所使用的跨库table或viewQ不方便校验。
2、开发h员在提交SP前,必须已经使用set showplan on分析q查询计划,做过自n的查询优化检查?
3、高E序q行效率Q优化应用程序,在SP~写q程中应该注意以下几点:
a)SQL的用规范:
i. 量避免大事务操作,慎用holdlock子句Q提高系lƈ发能力?/font>
ii. 量避免反复讉K同一张或几张表,其是数据量较大的表Q可以考虑先根据条件提取数据到临时表中Q然后再做连接?/font>
iii. 量避免使用游标Q因为游标的效率较差Q如果游标操作的数据过1万行Q那么就应该改写Q如果用了游标Q就要尽量避免在游标循环中再q行表连接的操作?/font>
iv. 注意where字句写法Q必考虑语句序Q应该根据烦引顺序、范围大来定条g子句的前后顺序,可能的让字D顺序与索引序怸_范围从大到小?/font>
v. 不要在where子句中的?”左边进行函数、算术运或其他表达式运,否则pȝ可能无法正用烦引?/font>
vi. 量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用Q而且count(1)比count(*)更有效率?/font>
vii. 量使用?gt;=”,不要使用?gt;”?/font>
viii. 注意一些or子句和union子句之间的替?/font>
ix. 注意表之间连接的数据cdQ避免不同类型数据之间的q接?/font>
x. 注意存储q程中参数和数据cd的关pR?/font>
xi. 注意insert、update操作的数据量Q防止与其他应用冲突。如果数据量过200个数据页面(400kQ,那么pȝ会q行锁升U,锁会升成表U锁?
b)索引的用规范:
i. 索引的创与应用结合考虑Q徏议大的OLTP表不要超q?个烦引?/font>
ii. 可能的使用索引字段作ؓ查询条gQ尤其是聚簇索引Q必要时可以通过index index_name来强制指定烦?/font>
iii. 避免对大表查询时q行table scanQ必要时考虑新徏索引?/font>
iv. 在用烦引字D作为条件时Q如果该索引是联合烦引,那么必须使用到该索引中的W一个字D作为条件时才能保证pȝ使用该烦引,否则该烦引将不会被用?/font>
v. 要注意烦引的l护Q周期性重建烦引,重新~译存储q程。
c)tempdb的用规范:
i. 量避免使用distinct、order by、group by、having、join、cumputeQ因些语句会加重tempdb的负担?/font>
ii. 避免频繁创徏和删除时表Q减系l表资源的消耗?/font>
iii. 在新Z时表Ӟ如果一ơ性插入数据量很大Q那么可以用select into代替create tableQ避免logQ提高速度Q如果数据量不大Qؓ了缓和系l表的资源,先create tableQ然后insert?/font>
iv. 如果临时表的数据量较大,需要徏立烦引,那么应该创Z时表和徏立烦引的q程攑֜单独一个子存储q程中,q样才能保证pȝ能够很好的用到该时表的烦引?/font>
v. 如果使用C临时表,在存储过E的最后务必将所有的临时表显式删除,先truncate tableQ然后drop tableQ这样可以避免系l表的较长时间锁定?/font>
vi. 慎用大的临时表与其他大表的连接查询和修改Q减低系l表负担Q因U操作会在一条语句中多次使用tempdb的系l表。
d)合理的算法用:
Ҏ上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,l合实际应用,采用多种法q行比较,以获得消耗资源最、效率最高的Ҏ。具体可用ASE调优命oQset statistics io on, set statistics time on , set showplan on {?br />