从数据库服务器端考虑:比如csdn只选出前300行纪录,因为用户不需要那么多纪录。你也不必把1000万条全部分页。你也不必把纪录放在一个表中,一年(太多就一个月)的数据放一张表或定期把历史数据导出到数据数据仓库中,不要用一张表装1000万条记录。做好索引。优化查询!尽量少用模糊查询,避免表扫描。不能让客户端连续多次搜索(csdn就是)
千万级的数据库,有分页的意义吗?对于用户来说就是信息的海洋了,去看看Google怎么做的吧,
根本就不存在如何分页的问题,如果一个结果有千万条,那跟没有结果一样是没有一样.应该是统计条数,取出,前N条进行分页,如果到地还在准备分页的话,再次取结果n,进行分页.并且在其间推荐用户进行递进式搜索,来降低信息量,才式正确的
我有一个方法:(对于喜欢用select * 的同行可能有用)
先检索出来,符合条件的所有 id (唯一标识)放在内存里
然后根据当前页数和每页多少行纪录 去内存中取 id号的当前集
根据当前集 中的某一条 去数据库中检索相应的数据行
这里建议使用编译预处理PrepareStatement
将结果放进数据类 (如果你的数据只有两列当然可以省略这一步)
然后把数据类添加进 ArrayList 或者HashMap
然后 把载页面上输出 ArrayList 或者HashMap 的数据
这样做,是因为只检索一列数据 要比检索多类要快得多 占用更少的内存。
一次只精确定位一条纪录 要比一次取出多条要快,这里的瓶颈在于频繁的与数据库交互,但是我们使用编译预处理可以很大程度上提高性能。
千万数量级分页存储过程(可支持多表查询,任意排序)
功能不错的分页存储过程,可支持多表查询,任意排序
CreatePROCEDUREusp_PagingLarge
@TableNamesVARCHAR(200),--表名,可以是多个表,但不能用别名
@PrimaryKeyVARCHAR(100),--主键,可以为空,但@Order为空时该值不能为空
@FieldsVARCHAR(200),--要取出的字段,可以是多个表的字段,可以为空,为空表示select*
@PageSizeINT,--每页记录数
@CurrentPageINT,--当前页,0表示第1页
@FilterVARCHAR(200)='',--条件,可以为空,不用填where
@GroupVARCHAR(200)='',--分组依据,可以为空,不用填groupby
@OrderVARCHAR(200)=''--排序,可以为空,为空默认按主键升序排列,不用填orderby
AS
BEGIN
DECLARE@SortColumnVARCHAR(200)
DECLARE@OperatorCHAR(2)
DECLARE@SortTableVARCHAR(200)
DECLARE@SortNameVARCHAR(200)
IF@Fields=''
SET@Fields='*'
IF@Filter=''
SET@Filter='Where1=1'
ELSE
SET@Filter='Where'+@Filter
IF@Group<>''
SET@Group='GROUPBY'+@Group
IF@Order<>''
BEGIN
DECLARE@pos1INT,@pos2INT
SET@Order=REPLACE(REPLACE(@Order,'asc','ASC'),'desc','DESC')
IFCHARINDEX('DESC',@Order)>0
IFCHARINDEX('ASC',@Order)>0
BEGIN
IFCHARINDEX('DESC',@Order)<CHARINDEX('ASC',@Order)
SET@Operator='<='
ELSE
SET@Operator='>='
END
ELSE
SET@Operator='<='
ELSE
SET@Operator='>='
SET@SortColumn=REPLACE(REPLACE(REPLACE(@Order,'ASC',''),'DESC',''),'','')
SET@pos1=CHARINDEX(',',@SortColumn)
IF@pos1>0
SET@SortColumn=SUBSTRING(@SortColumn,1,@pos1-1)
SET@pos2=CHARINDEX('.',@SortColumn)
IF@pos2>0
BEGIN
SET@SortTable=SUBSTRING(@SortColumn,1,@pos2-1)
IF@pos1>0
SET@SortName=SUBSTRING(@SortColumn,@pos2+1,@pos1-@pos2-1)
ELSE
SET@SortName=SUBSTRING(@SortColumn,@pos2+1,LEN(@SortColumn)-@pos2)
END
ELSE
BEGIN
SET@SortTable=@TableNames
SET@SortName=@SortColumn
END
END
ELSE
BEGIN
SET@SortColumn=@PrimaryKey
SET@SortTable=@TableNames
SET@SortName=@SortColumn
SET@Order=@SortColumn
SET@Operator='>='
END
DECLARE@typevarchar(50)
DECLARE@precint
Select@type=t.name,@prec=c.prec
FROMsysobjectso
JOINsyscolumnscono.id=c.id
JOINsystypestonc.xusertype=t.xusertype
Whereo.name=@SortTableANDc.name=@SortName
IFCHARINDEX('char',@type)>0
SET@type=@type+'('+CAST(@precASvarchar)+')'
DECLARE@TopRowsINT
SET@TopRows=@PageSize*@CurrentPage+1
print@TopRows
print@Operator
EXEC('
DECLARE@SortColumnBegin'+@type+'
SETROWCOUNT'+@TopRows+'
Select@SortColumnBegin='+@SortColumn+'FROM'+@TableNames+''+@Filter+''+@Group+'orDERBY'+@Order+'
SETROWCOUNT'+@PageSize+'
Select'+@Fields+'FROM'+@TableNames+''+@Filter+'AND'+@SortColumn+''+@Operator+'@SortColumnBegin'+@Group+'orDERBY'+@Order+'
')
END
GO
--调用例子:
--1.单表/单排序
EXECusp_PagingLarge'bigtable','d_id','d_id,d_title,d_content,d_time',20,1,'','','d_iddesc'
--2.单表/多排序
EXECusp_PagingLarge'bigtable','d_id','*',20,0,'','','d_timeasc,d_iddesc'
--3.多表/单排序
EXECusp_PagingLarge'bigtableleftjoinbigtable_authoronbigtable.d_id=bigtable_author.BigTable_id','bigtable.d_id','bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author',20,0,'','','bigtable.d_idasc'
--4.多表/多排序
EXECusp_PagingLarge'bigtableleftjoinbigtable_authoronbigtable.d_id=bigtable_author.BigTable_id','bigtable.d_id','bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author',20,0,'','','bigtable.d_timeasc,bigtable.d_iddesc'