我刚刚发现了 TABLESAMPLE
子句,但令人惊讶的是它没有返回我指定的行数。
我使用的表有大约1400万行,我想要10000行的任意样本。
select * from tabData TABLESAMPLE(10000 ROWS)
每次执行时,我得到的不是10000,而是一个不同的数字(介于8000和14000之间)。
这是怎么回事,我是否误解了
TABLESAMPLE
的预期目的?编辑:
David's link很好地解释了这一点。
这将以有效的方式始终返回10000个大致随机的行:
select TOP 10000 * from tabData TABLESAMPLE(20000 ROWS);
和
REPEATABLE
选项有助于始终保持一致(除非数据已更改)select TOP 10000 * from tabData TABLESAMPLE(10000 ROWS) REPEATABLE(100);
由于我想知道使用带有大量行的
TABLESAMPLE
来确保我获得正确的行号是否更昂贵,因此我进行了测量;1.循环(20次):
select TOP 10000 * from tabData TABLESAMPLE(10000 ROWS);
(9938 row(s) affected)
(10000 row(s) affected)
(9383 row(s) affected)
(9526 row(s) affected)
(10000 row(s) affected)
(9545 row(s) affected)
(9560 row(s) affected)
(9673 row(s) affected)
(9608 row(s) affected)
(9476 row(s) affected)
(9766 row(s) affected)
(10000 row(s) affected)
(9500 row(s) affected)
(9941 row(s) affected)
(9769 row(s) affected)
(9547 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(9478 row(s) affected)
First batch(only 10000 rows) completed in: 14 seconds!
2.循环(20次):
select TOP 10000 * from tabData TABLESAMPLE(10000000 ROWS);
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
Second batch(max rows) completed in: 13 seconds!
3.循环:使用ORDER BY NEWID()对100%随机行进行复查:
select TOP 10000 * from tabData ORDER BY NEWID();
(10000 row(s) affected)
在执行一次持续 23分钟后取消
结论:
因此,令人惊讶的是,使用精确的
TOP
子句并在TABLESAMPLE
中包含大量数字的方法是,而不是较慢。因此,如果行不是不是每行而是每个页面级别都是随机的,那么它是ORDER BY NEWID()
的非常有效的替代方法(表的每个8K页面都被赋予了一个随机值)。 最佳答案
参见article here。您需要添加top子句和/或使用repeatable选项来获取所需的行数。
关于sql-server - TABLESAMPLE返回错误的行数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10725839/