今天说一下 tablesample 这个东西
TableSample 平时用得少,基本上就是用于表里面抽样数据来看的。
用法如下
SELECT * FROM tbname TABLESAMPLE SYSTEM (N PERCENT/M Rows) REPEATABLE()
TABLESAMPLE SYSTEM 这个表示使用System的方法进行数据抽样。(目前我也只知道有System这个方法)
N PERCENT/M Rows 可以选择抽样多少行,也可以抽样多少百分比
REPEATABLE 关键字里面还可以填入一个种子值,填充了之后每次可以得到一致的结果。
下面做实验,创建一个测试表
CREATE TABLE [dbo].[Tmp123] ( [ID] [int] NOT NULL IDENTITY(1, 1), [Col1] [char] (200) ) ON [PRIMARY] GO
塞进去500条数据
INSERT INTO dbo.Tmp123 ( Col1 ) VALUES ( 'abcd' ) GO 500
大概看了一下下,DBCC IND('Test','Tmp123',-1) 占用了15个数据页,然后我们使用 tablesample 来进行抽样
SELECT * FROM dbo.Tmp123 TABLESAMPLE (25 ROWS)
这里执行之后发现。大概2次有1次没有返回任何数据,然而返回的数据也并不是准确的25条。
这就是TableSample 的特性,是因为sql server 会根据System方法随机决定是否要读取该数据页的数据进行显示,只能说,请求的行数越多,会越接近TableSample里面请求的行数。
那我们就可以进行一个变形
SELECT top 25 * FROM dbo.Tmp123 TABLESAMPLE (25 ROWS)
加上Top 去控制,那么得到的行,最多是25行,但是也会有少于25行的情况出现。so ……你懂的~
然后再说下我了解到的情况,为什么返回的几率是差不多一半一半呢?是这样纸的
1、这个表占用了15个数据页,总数据量是500条,我请求了25条 ,占比是 25/500 = 5% (是的,无论请求行数还是百分比,都会转换为百分比进行运算)
2、那么每个数据页的读取可能性就是 5% 了~一共15个数据页,其中没有结果返回的概率是 (1-5%)^15 = 43% ,差不多50%,所以调用的时候就觉得一半一半,样例越多越趋近这个结果
3、那如果现实的行比实际多,也是因为这个概率问题。如果表里面的数据越多,请求的行数越多,越接近请求的值。
4、如果真想精确的控制行数来实现随机,那么请用
SELECT top 25 * FROM dbo.Tmp123 ORDER BY NewID()
好~说完了~