惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
L
LangChain Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
美团技术团队
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium
D
DataBreaches.Net
P
Proofpoint News Feed
小众软件
小众软件
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
雷峰网
雷峰网
G
Google Developers Blog

博客园 - 文刀无尽

在Django 中更新mongodb的ListField字段 图片加到json中,提交到服务器端处理异常问题。 在django中使用时django-nonrel,'django.contrib.auth'不能用的问题 在mac 上安装 mpkg 在bluehost上安装mongodb Celery使用数据库代替rabbitmq 为什么要使用Rabbitmq 在bluehost上安装pytoh 2.7.2 为android 启动的时候添加splash 折腾了半天,ajax 在模拟器下正常,在一台2.1机器上正常,在我的小米2.3下不工作 去掉默认标题栏且将应用设置为全屏 java 基本语法 在jquery mobile中页面跳转的时候,实现登录检查 去掉jquery mobile 的阴影效果 Eclipse 的 javascript 插件 iphone phonegap中跨域的问题 使用jquery mobile 经验 (原创)自已实现服务器控件之 TextBox 控件 (原创)自已实现服务器控件系列 之 设计时可用鼠标拖动大小的Label控件
另类随机读大表数据
文刀无尽 · 2009-05-01 · via 博客园 - 文刀无尽

想到写这个存储过程,是由于做频道首页的时候,需要从表中取随机的N行记录。
但由于表比较大,十几万条记录,如果再用order by newid()这样的方式从数据库
读取数据,本身order by 就慢,再加上newid(),就慢上加慢。
后来想了很久,决定用随机从数据库中随机取一页数据的方式。虽然做不到离散方式
的随机,虽然是集中式的,但也是随机地取数据了。

我做的分页是写在程序里的,当然,放在程序里和作为一个存储过程,有好有坏,在这里,
我就不作专门的请讨论。

注意事项:
1.一定要对排序字段建索引,建与不建索引,速度的差别是很大的。
2.由于之前分布在程序中进行,现在这个分布存储过程,只用于随机取数据
所以还没有经过太多的测试。
下面是存储过程脚本

Code:

/*----------------------------
Author     :Nick.Liu
CreatedDate:2008-12-23

CopyRight:http://www.dreampea.com //使用请保留这里
功能:
1.实现查询分页功能
2.随机读取一页数据
输入参数说明:
@Source :数据源,可以是一个查询语句
@PageSize:一页大小,-1为查询所有页,-2为查询随机页
@RowIDOrderString :排序规则 格式:字段名 desc/asc
@CurrentPageIndex :当前页,由1开始

输出:
表1:当前页数据
表2:@Source 的行数
修改记录:

-----------------------------*/
CREATE Proc [dbo].[Proc_Pager]
@Source nvarchar(1000)
,@PageSize int
,@RowIDOrderString nvarchar(200)
,@CurrentPageIndex int

as
DECLARE @SQLString nvarchar(500);
declare @SqlQuery nvarchar(2000)
DECLARE @ParmDefinition nvarchar(500);
DECLARE @QueryParmDefinition nvarchar(500);
DECLARE @CountOut varchar(30);

SET @SQLString = N'SELECT @Count = count(1)
   FROM ('+@Source+') a'
SET @ParmDefinition = N'@Count int OUTPUT';
SET @QueryParmDefinition = N'@BeginIndexInner bigint,@EndIndexInner bigint';

EXECUTE sp_executesql @SQLString, @ParmDefinition, @Count=@CountOut OUTPUT;
declare @Pages int
set @Pages = @CountOut/@PageSize
if @CurrentPageIndex = -2
Begin
set @CurrentPageIndex = cast(@Pages*Rand() as int)
End

declare @BeginIndex  bigint
declare @EndIndex  bigint

set @BeginIndex = @PageSize*(@CurrentPageIndex-1)
set @EndIndex = @PageSize*@CurrentPageIndex

set @SqlQuery = 'select RowCnt,* from
                        (
                            select ROW_NUMBER() OVER(order by '+@RowIDOrderString+') as RowCnt
                            ,* from ('+@Source+') a
                        )a'
    if(@CurrentPageIndex != -1)
    Begin
             set @SqlQuery = @SqlQuery+ ' where RowCnt > @BeginIndexInner
                        and RowCnt <=@EndIndexInner'
    End
print @sqlQuery
EXECUTE sp_executesql @SqlQuery,@QueryParmDefinition,@BeginIndexInner= @BeginIndex,@EndIndexInner= @EndIndex
exec('select RowCnt=count(1) from ('+@Source+') a')