22,209
社区成员
发帖
与我相关
我的任务
分享
-------------------- 准备测试表,生成 100 万条测试数据 ---------------------
USE tempdb
GO
IF OBJECT_ID('tempdb..info_data') IS NOT NULL
DROP TABLE info_data
GO
CREATE TABLE info_data(
dataId bigINT IDENTITY(1,1) PRIMARY KEY,
n NVARCHAR(MAX)
)
GO
SET NOCOUNT ON
DECLARE @i INT,@iMax INT
SET @iMax=1000000
WHILE 1=1
BEGIN
SELECT @i=COUNT(1) FROM info_data
PRINT @i
IF @i>=@imax
BEGIN
BREAK;
END
IF @i=0
BEGIN
INSERT INTO info_data (n) VALUES(N'xxxxxxxxxxxxxxx')
END
IF @i<=@imax/2
BEGIN
INSERT INTO info_data (n)
SELECT n FROM info_data
END
ELSE
BEGIN
INSERT INTO info_data (n)
SELECT TOP( @iMax-@i ) n FROM info_data
END
END
-- 100 万数据就 6 秒
----------------------- 下面是正式的过程 ------------------------------
--1. 准备一个正式的临时中转表
--之所以准备这个中转表, 是因为数据表即使是 标识列(自增),
--但实际上不可能是完全有顺序的
--中转表用于大批量分页是非常合适的
IF OBJECT_ID('tmp_loop') IS NOT NULL
DROP TABLE tmp_loop
CREATE TABLE tmp_loop(
id INT IDENTITY(1,1) PRIMARY KEY,
dataId BIGINT,
INDEX ix_tmp_loop_dataId ( dataId )
)
--插入所有主键到中转表 ( 9s )
INSERT INTO tmp_loop(dataId)
SELECT dataId FROM info_data;
--以分页方式遍历所有记录,文本显示,( 1 m 24 s )
DECLARE @j INT,@jMax INT,@step INT
SELECT @j=0,@jMax=MAX(id) FROM tmp_loop;
SET @step = 1000;
WHILE @j+@step<=@jMax
BEGIN
SELECT a.*
FROM info_data AS a INNER JOIN tmp_loop AS b
ON a.dataId=b.dataId
AND b.id>@j AND b.id<=@j+1000;
SET @j=@j+@step;
END
了解思路, 后面随便你用存储过程, 还是用程序, 都很容易。
至于什么数据不断在增加, 不需要管。
我的做法是取某一时刻的数据, 后面新增的不管。
因为即使你取了后面新增的,你刚取完,后面又增加了, 那你永远没有停止的时候。