您可以尝试一次填充您的表格,在每次迭代时将第一列的值增加 1。
先决条件:
- 决定列的数据类型。这些值在 1-90 之间,它们适合 tinyint(1 字节)而不是 null。 6 列 = 6 个字节
- 创建唯一的聚集索引,因为列的组合是唯一的。一个堆会为 RID 增加 8 字节的开销,为唯一值增加 4 字节的非唯一聚集索引(所有六列只有 6 字节)
- 提供数据库(可用空间+恢复模型):
(六列 x 1 字节 + 约 8 字节行开销)x 620mil = 数据库中约 9-10GB 的可用空间/存储空间,并最大限度地减少数据文件自动增长的开销。
如果可能,最好将 db 的恢复模式更改为 simple(以防止 log out of space 错误)。
如果空间使用很重要(并且有足够的 cpu 用于稍后增加的成本),您还可以考虑对“数字”表进行页面压缩。
创建数字表:
create table dbo.numstable
(
a tinyint not null,
b tinyint not null,
c tinyint not null,
d tinyint not null,
e tinyint not null,
f tinyint not null,
constraint pknumstable primary key clustered(a,b,c,d,e,f)
);
go
并填充它,一次一个列“a”值:
declare @maxa int = (select isnull(max(a), 0)+1 from dbo.numstable);
select @maxa = case when @maxa <= 85 then @maxa end;
declare @Numbers table (N tinyint primary key clustered);
insert into @Numbers(N)
select rownum --cast?
from
(
select top (90) row_number() over(order by rand()) as rownum
from master.dbo.spt_values
) as r
where rownum >= @maxa;
insert into dbo.numstable with (tablock)
(a,b,c,d,e,f)
SELECT N1.N as a, N2.N as b, N3.N as c, N4.N as d, N5.N as e, N6.N as f
FROM @Numbers N1
JOIN @Numbers N2 ON N2.N > N1.N
JOIN @Numbers N3 ON N3.N > N2.N
JOIN @Numbers N4 ON N4.N > N3.N
JOIN @Numbers N5 ON N5.N > N4.N
JOIN @Numbers N6 ON N6.N > N5.N
where N1.N = @maxa
order by N1.N, N2.N, N3.N, N4.N, N5.N, N6.N;
go 85 --iterate 85 times
如果在填充期间发生错误,请修复并再次执行填充脚本(原样)。
如果吞吐量约为 1500 万行/分钟(最坏情况),则完全填充表需要大约 40 分钟。
查询表时,您可以“利用”数据/值的性质:
--instead of ...
select count(*)
from dbo.numstable
where c = 7
and e = 44;
--...better...
select count(*)
from dbo.numstable
where a in (1, 2, 3, 4, 5)
and b in (2, 3, 4, 5, 6)
and c = 7
and e = 44;