主要是被搞得一头雾水,在学校里老师就说sqlserver2000很差,比mysql都不如,希望2005的能好一点,唉
解决方案 »
- 【提问】几段JS兼容性问题---->标题要长
- 怎样用TreeView控件做出电脑左侧任务栏一样的效果?
- 技术求助
- 实现 GridView 统计 问题
- cookie 什么时候消失?如果页面都关掉了,cookie还存在,不就是不要登陆了吗?
- 菜鸟提问!如何实现记录登陆人员的状态???
- 请教:如何在net下用infopath2003开发web程序
- 100分求Together for VS .NET 1.0.1 注册码、注册机
- 高手请进!关于窗体间数据传递的问题!(100分)
- C# : inner join中自连接咋用,能否给个实例?
- 100分,谁知道微软vs2005 sp1下载地址,急用
- 用DATALIST绑定的数据库中的用户
通用的 肯定 效率来说会 降低但是通用的 也可以很 容易 根据print输出写成特定的分页过程
用50万的数据量来测试就会很明显了,
另外 那种 where (1=1) 形式也是不可取的,因为这种形式不会使用索引的
还有那种什么 order by id 明显就是不可取,那个id必须是唯一健,侵入性非常强
sql 2000出道的时候, mysql都不支持存储过程,不支持事务,不支持左右全连接, 不支持嵌套查询,不支持全文索引,没有查询分析器,没有事件探查器,只有一个php的mysqladmin. 很久没用过了,不知道现在支不支持. 不过现在已经是sql 2005了当然我十分崇拜独立开发出mysql的那些个热血青年.
行号是聚簇索引,如果SQL Server的排序字段也建立聚簇索引,它们的效率是一样的,这点如果你的数据库老师没讲过,那说明他水平有限。SQL Server 2000和Oracle相比,各有优缺点。Oracle占用资源巨高,SQL Server 2000则在处理巨大量数据上效率低,且无法充分利用硬盘DMA通道的优势。一般数据量不是很大还是用SQL Server,如果上G的数据就选Oracle。
关于MySQL,和楼上观点一样,崇拜开发者,但其应用,也只能局限于网站这样数据量极小的情况了。
(-_______-...当然除了视图做过渡,不过这样就没意义了,速度慢了)
主要是被搞得一头雾水,在学校里老师就说sqlserver2000很差,比mysql都不如,希望2005的能好一点,唉
--------------
这样为人师 。。迷糊~~
select top [PageSize * (PageIndex - 1) + 1] * from Table where ID >= @ID这个效率就高了,当然不够通用。select top 10 [*] from
select top 10 [*] from
(
select top 20 [*] from [Table]
order by [AddedDate] desc,[ID]
) as aa order by [AddedDate] ,[ID] desc
) as aa order by [AddedDate] desc ,[ID] 这个就通用了, order by [AddedDate] desc,[ID] 这里还可以加更多的排序字段。至于多表联合可以做成视图来简化。至于效率,算法不是主要的,设置合理的索引才是最主要的!唯一的缺点:最后一个排序字段不能有重复值。有的话会影响排序,影响的程度要看重复值的多少和位置。不过也好解决,加一个自增字段就可以了。select [*] from [Table] where [ID] in (
select top 10 [ID] from
(
select top 20 [ID] ,AddedDate from [Table]
order by [AddedDate] desc,[ID]
) as aa order by [AddedDate] ,[ID] desc
)order by [AddedDate] desc,[ID]这是一个折衷的算法,通用和效率的折中,两者都是比较高的。详细看这里
http://blog.csdn.net/jyk/archive/2007/03/01/1518354.aspx
select top [PageSize * (PageIndex - 1) + 1] * from Table where ID >= @ID
我就是用这个,千万数据,ID,int,聚集索引,少于100毫秒
4.如果order by 字段的数据列包含空值,分页效果可能就会和实际的不符,不信的话可以试试
----------------------------------------*当然我也写不出什么比较好的分页存储过程,我使用过Hibernate,里面的sqlserver分页算法是基于两次Top三次颠倒数据集实现分页,Hibernate的作者Gaving King也算是个数据库专家,这说明第一种方案还是比较通用的,有批评才有进步,才会想出更好的方法出来,我是这么想的
-----------------------------------------*2005的基于行号的分页有空要试试
-----------------------------------------
*我上面写的那个存储过程是仓促之作,如果多表连接再加上排序就要出问题了,主要是那个order by字段的表前缀处理不好,会解决的_________________________________________
*至于mysql和mssql哪个好,我也不想去讨论,可能mssql用得比较多,才觉得它很差,这个毛病那个毛病的,如果你有开发java,你就知道mssql又要多几种差的地方,正如微软window系统用的人多,结果找出来的毛病也多一样,虽然我写不出数据库,在这里我就好像是客户在使用了一种产品以后点出了一些感慨-----------------------------------------
*贴一个oracle分页,有比较才知道不足
SELECT * FROM (
SELECT my_table.* , rownum AS my_number FROM (
/** 这里写实际的需要查询的SQL语句,爱什么写就怎么写,主动权在程序员**/
select * from mytable where ... order by ... ) AS my_table WHERE rownum <=30 /**这里是一页中的最后一条记录**/ ) WHERE my_number >=20 /**这里是一页中的第一条记录**/
*当然oracle是sqlserver不能比的,但我相信微软那么的开发人员系统都能开发,把sqlserver的分页稍微搞得简便一点咋就没有办法办到?? 估计微软只做大事不做小事-------------------------------------
算了无所谓啦,随便开发吧,有什么用什么,研究知道得太多对自己也没有什么好处,反而经常要想着如果去改进
--两次top分页方案,如果最后一页纪录数目不足规定的页大小,会自动补足纪录数
alter proc com_Pagination
@tbName varchar(200), --表名,可多表,逗号分隔
@tbFields varchar(500)='*',--字段名,如果多表请带前缀
@whereStr varchar(300)='', --where子句,可为空,不带where
@orderStr varchar(300), --排序字段,可多个,要带desc或asc,不带order by,必须,不能为空,多表要带前缀a-e
--排序字段不能有空值,或者在where中排除空值或者用isnull函数解决@needCound bit = 0, --是否需要得到纪录总数
@pageIndex int =0, --页索引
@pageSize int=10, --页大小
@recordCount BIGINT =0 output, --返回纪录总数,如果用DataReader提取过程结果集,必须dr.close或者conn.close,才能获得过程的返回值,oracle中的DataReader不会有这种情况
@pageCount int =0 output --返回页总数as
declare @sql nvarchar(1300) --主sql语句
declare @orderStr2 varchar(300) --order by子句
declare @orderStr3 varchar(300) --order by子句
declare @tempStr varchar(300)set @orderStr = LOWER(@orderStr)
set @tempStr = REPLACE(@orderStr,' desc','')
set @tempStr = REPLACE(@tempStr,' asc','')
set @tbFields = @tbFields + ',' + @tempStr
set @orderStr2 = REPLACE(@orderStr,' desc',' @a@')
set @orderStr2 = REPLACE(@orderStr2,' asc',' @d@')
set @orderStr2 = REPLACE(@orderStr2,' @a@',' asc')
set @orderStr2 = REPLACE(@orderStr2,' @d@',' desc')set @orderStr3 = REPLACE(@orderStr,'a.','')
set @orderStr3 = REPLACE(@orderStr3,'b.','')
set @orderStr3 = REPLACE(@orderStr3,'c.','')
set @orderStr3 = REPLACE(@orderStr3,'d.','')
set @orderStr3 = REPLACE(@orderStr3,'e.','')set @orderStr = ' order by ' + @orderStr
set @orderStr2 = ' order by ' + @orderStr2
set @orderStr3 = ' order by ' + @orderStr3 if(@whereStr is not null and @whereStr !='' )
set @whereStr = ' where ' + @whereStr
else
set @whereStr = '' if(@needCound != 0 or @pageIndex = 0) --以下获得纪录总数
begin
DECLARE @R BIGINT
SET @sql= N'select @R=count(*) from '+@tbName +@whereStr
EXEC SP_EXECUTESQL @SQL,N'@R BIGINT OUTPUT',@R OUTPUT
SET @recordCount = @R
set @pageCount = ((@recordCount-1)/@pageSize)+1
end
if(@pageIndex<2) --如果是第一页
begin
set @pageIndex = 1
set @sql='select top '+ str(@pageSize) + ' '+ @tbFields + ' from ' + @tbName + @whereStr + @orderStr;
end
else --其它页
begin
SET @sql= 'SELECT * FROM ('
+ 'SELECT TOP ' + STR(@pageSize) + ' * FROM ('
+ 'select top ' + STR(@pageSize*@pageIndex) + ' '+ @tbFields + ' FROM '
+ @tbName + @whereStr + @orderStr + ') as a'
+ @orderStr2 + ') as b' + @orderStr3
end
print @sql
EXEC SP_EXECUTESQL @sql
--测试
--pub数据库,三表连接,结果集43条,页大小10,但第五页还是10条(有一些是重复纪录)
declare @a BIGINT,@b BIGINT
exec com_Pagination 'employee a,jobs b,publishers c','a.emp_id,a.fname+a.lname as ename,b.job_desc,c.pub_name','a.job_id=b.job_id and a.pub_id=c.pub_id','a.hire_date desc',true,4,10,@a output,@b output
print @a
print @b--原始的结果集,分页就是基于下面这个
select * from employee e,jobs j,publishers p where e.job_id=j.job_id and e.pub_id=p.pub_id order by hire_date desc
有它的弊病,建议不要(我指的是一些比较重要的表噢)sqlserver的分页好与不好,争论太多于事无补,随便搜一个sqlserver的分页存储过程,有哪一篇不是长篇大论的看得你眼皮发抖,这足以证明sqlserver的分页方案确实不好,繁琐,侵入性!!有待我们再去改善,有待我们再去探讨,贴这篇文章的目的是想问问网友们有没有更好的方案,如何做?有谁认为sqlserver的那几种分页方案挺好的!请站出来说它好的地方