摘要: selecttop页大小* fromtable1 whereid> (selectmax(id)from (selecttop((页码-1)*页大小)idfromtable1orderbyid)asT ) orderbyid 在大数据量的情况下,特别是在查询最后几页的时候,查询时间一般不会超过9秒;而用其他存储过程,在实践中就会导致超时,所以这个存储过程非常适用于大容量数据库的查询。 笔者希望能够通过对以上存储过程的解析,能给大家带来一定的启示,并给工作带来一定的效率提升,同时希望同行提出更优秀的实时数据分页算法. 四、聚集索引的重要性和如何选择聚集索引 在上一... 阅读全文
posted @ 2012-02-22 11:03 zrj531 阅读(364) 评论(0) 推荐(0) 编辑
摘要: 在选择即不重复值,又容易分辨大小的列时,我们通常会选择主键。下表列出了笔者用有着1000万数据的办公自动化系统中的表,在以GID(GID是主键,但并不是聚集索引。)为排序列、提取gid,fariqi,title字段,分别以第1、10、100、500、1000、1万、10万、25万、50万页为例,测试以上三种分页方案的执行速度:(单位:毫秒) 页 码方案1方案2方案3160307610461663100107672013050054012943831000171104702501万24796450014010万3832642283155325万28140128720 233050万1216861 阅读全文
posted @ 2012-02-22 11:02 zrj531 阅读(455) 评论(0) 推荐(0) 编辑
摘要: 但这个存储过程有一个致命的缺点,就是它含有NOT IN字样。虽然我可以把它改造为: SELECT TOP 页大小 * FROM Table1 WHERE not exists (select * from (select top (页大小*页数) * from table1 order by id) b where b.id=a.id ) order by id 即,用not exists来代替not in,但我们前面已经谈过了,二者的执行效率实际上是没有区别的。 既便如此,用TOP 结合NOT IN的这个方法还是比用游标要来得快一些。 虽然用not exists并不能挽救上... 阅读全文
posted @ 2012-02-22 11:00 zrj531 阅读(282) 评论(0) 推荐(0) 编辑
摘要: 笔者曾在网上看到了一篇小短文《从数据表中取出第n条到第m条的记录的方法》,全文如下: 从publish 表中取出第 n 条到第 m 条的记录:SELECT TOP m-n+1 * FROM publish WHERE (id NOT IN (SELECT TOP n-1 id FROM publish)) id 为publish 表的关键字 我当时看到这篇文章的时候,真的是精神为之一振,觉得思路非常得好。等到后来,我在作办公自动化系统(ASP.NET+ C#+SQL SERVER)的时候,忽然想起了这篇文章,我想如果把这个语句改造一下,这就可能是一个非常好的分页存储过程。于是我就满网... 阅读全文
posted @ 2012-02-22 10:59 zrj531 阅读(227) 评论(0) 推荐(0) 编辑
摘要: 12、高效的TOP 事实上,在查询和提取超大容量的数据集时,影响数据库响应时间的最大因素不是数据查找,而是物理的I/0操作。如: select top 10 * from ( select top 10000 gid,fariqi,title from tgongwen where neibuyonghu='办公室'order by gid desc) as a order by gid asc 这条语句,从理论上讲,整条语句的执行时间应该比子句的执行时间长,但事实相反。因为,子句执行后返回的是10000条记录,而整条语句仅返回10条语句,所以影响数据库响应时间最大的因素是物理 阅读全文
posted @ 2012-02-22 10:58 zrj531 阅读(560) 评论(0) 推荐(0) 编辑
摘要: 10、count(*)不比count(字段)慢 某些资料上说:用*会统计所有列,显然要比一个世界的列名效率低。这种说法其实是没有根据的。我们来看: select count(*) from Tgongwen 用时:1500毫秒 select count(gid) from Tgongwen 用时:1483毫秒 select count(fariqi) from Tgongwen 用时:3140毫秒 select count(title) from Tgongwen 用时:52050毫秒 从以上可以看出,如果用count(*)和用count(主键)的速度是相当的,而count... 阅读全文
posted @ 2012-02-22 10:56 zrj531 阅读(424) 评论(0) 推荐(0) 编辑
摘要: 8、union并不绝对比or的执行效率高 我们前面已经谈到了在where子句中使用or会引起全表扫描,一般的,我所见过的资料都是推荐这里用union来代替or。事实证明,这种说法对于大部分都是适用的。 select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16' or gid>9990000 用时:68秒。扫描计数 1,逻辑读 404008 次,物理读 283 次,预读 392163 次。 select gid,fariqi,neibuyonghu,reader,titl 阅读全文
posted @ 2012-02-22 10:54 zrj531 阅读(302) 评论(0) 推荐(1) 编辑
摘要: 5、尽量少用NOT 6、exists 和 in 的执行效率是一样的 很多资料上都显示说,exists要比in的执行效率要高,同时应尽可能的用not exists来代替not in。但事实上,我试验了一下,发现二者无论是前面带不带not,二者之间的执行效率都是一样的。因为涉及子查询,我们试验这次用SQL SERVER自带的pubs数据库。运行前我们可以把SQL SERVER的statistics I/O状态打开。 (1)select title,price from titles where title_id in (select title_id from sales where qt... 阅读全文
posted @ 2012-02-22 10:52 zrj531 阅读(310) 评论(0) 推荐(0) 编辑
摘要: 介绍完SARG后,我们来总结一下使用SARG以及在实践中遇到的和某些资料上结论不同的经验: 1、Like语句是否属于SARG取决于所使用的通配符的类型 如:name like ‘张%’ ,这就属于SARG 而:name like ‘%张’ ,就不属于SARG。 原因是通配符%在字符串的开通使得索引无法使用。 2、or 会引起全表扫描 如:Name=’张三’ and 价格>5000 符号SARG, 而:Name=’张三’ or 价格>5000 则不符合SARG。 使用or会引起全表扫描。 3、非操作符、函数引起的不满足SARG形式的语句 不满足SARG形式的语句最典型的情况就... 阅读全文
posted @ 2012-02-22 10:51 zrj531 阅读(321) 评论(0) 推荐(0) 编辑
摘要: 二、改善SQL语句 很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。比如: select * from table1 where name='zhangsan' and tID > 10000 和执行: select * from table1 where tID > 10000 and name='zhangsan' 一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的10000条以后的记 阅读全文
posted @ 2012-02-22 10:50 zrj531 阅读(298) 评论(0) 推荐(0) 编辑
摘要: 4 、日期列不会因为有分秒的输入而减慢查询速度 下面的例子中,共有100万条数据,2004年1月1日以后的数据有50万条,但只有两个不同的日期,日期精确到日;之前有数据50万条,有5000个不同的日期,日期精确到秒。 select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>'2004-1-1' order by fariqi 用时:6390毫秒 select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi< 阅读全文
posted @ 2012-02-22 10:49 zrj531 阅读(327) 评论(0) 推荐(0) 编辑
摘要: (四)其他书上没有的索引使用经验总结 1、用聚合索引比用不是聚合索引的主键速度快 下面是实例语句:(都是提取25万条数据) select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16' 使用时间:3326毫秒 select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid<=250000 使用时间:4470毫秒 这里,用聚合索引比用不是聚合索引的主键速度快了近1/4。 2、用聚合索引比用一般的主键作or 阅读全文
posted @ 2012-02-22 10:48 zrj531 阅读(319) 评论(0) 推荐(0) 编辑
摘要: 2、只要建立索引就能显著提高查询速度 事实上,我们可以发现上面的例子中,第2、3条语句完全相同,且建立索引的字段也相同;不同的仅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查询速度却有着天壤之别。所以,并非是在任何字段上简单地建立索引就能提高查询速度。 从建表的语句中,我们可以看到这个有着1000万数据的表中fariqi字段有5003个不同记录。在此字段上建立聚合索引是再合适不过了。在现实中,我们每天都会发几个文件,这几个文件的发文日期就相同,这完全符合建立聚集索引要求的:“既不能绝大多数都相同,又不能只有极少数相同”的规则。由此看来,我们建立“适当”的.. 阅读全文
posted @ 2012-02-22 10:47 zrj531 阅读(459) 评论(0) 推荐(0) 编辑
摘要: (三)结合实际,谈索引使用的误区 理论的目的是应用。虽然我们刚才列出了何时应使用聚集索引或非聚集索引,但在实践中以上规则却很容易被忽视或不能根据实际情况进行综合分析。下面我们将根据在实践中遇到的实际问题来谈一下索引使用的误区,以便于大家掌握索引建立的方法。 1、主键就是聚集索引 这种想法笔者认为是极端错误的,是对聚集索引的一种浪费。虽然SQL SERVER默认是在主键上建立聚集索引的。 通常,我们会在每个表中都建立一个ID列,以区分每条数据,并且这个ID列是自动增大的,步长一般为1。我们的这个办公自动化的实例中的列Gid就是如此。此时,如果我们将这个列设为主键,SQL SERVER会将... 阅读全文
posted @ 2012-02-22 10:46 zrj531 阅读(343) 评论(0) 推荐(0) 编辑
摘要: (一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别: 其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,.. 阅读全文
posted @ 2012-02-22 10:45 zrj531 阅读(595) 评论(0) 推荐(1) 编辑