【发布时间】:2018-02-11 15:24:19
【问题描述】:
我想查询一个相当大的表(数百万行),提供一个种子值,以保证随机顺序的方式 - 但只要使用相同的种子,该表在多个查询中保持稳定。
到目前为止我想出的最好的是
SELECT TOP n *
FROM tbl t
ORDER BY t.int_column % seed, t.int_column
无论从性能角度还是从结果行在不同种子上的稍微均匀分布的角度来看,这是一种可用的方法吗?
编辑:
对于上下文,需要稳定排序,因为多个(可能是嵌套的)WHERE NOT IN 查询对同一数据集进行操作;例如
SELECT *
FROM tbl t
WHERE t.some_criteria = 'some_value'
AND t.id NOT IN
(
SELECT TOP n t.id
FROM tbl t
WHERE t.some_other_criteria = 'some_other_value'
ORDER BY t.int_column % seed, t.int_column
)
AND t.id NOT IN
(
# etc.
)
当子选择的顺序是随机的,但不稳定(即NEWID()、TABLESAMPLE())时,结果行在执行之间波动很大。
【问题讨论】:
-
数据在哪里消费?如果您没有将数据传递给另一个存储过程或其他数据库内代码,那么根据非平凡标准对行进行排序的行为是一个视图级别的问题,不应该在您的数据库代码中,而是在您的应用程序中代码。
-
@Dai - 好问题。请查看我的编辑。
-
您将始终对符合条件的所有记录进行排序,这可能会很多。你确定你需要所有这些
NOT IN子句吗?也许您可以稍微简化查询。你到底想达到什么目的? -
@ThorstenKettner 是的,很遗憾。用例是根据用户提供的标准操作的选择构建器;每个子选择代表一个“左兄弟”目标组,其结果需要从下一个目标组的池中排除(因为每个实体永远只能是一个目标组的一部分)。
-
所以随着查询越来越大,您一次又一次地选择?对于已经包含排序键和索引的临时表,可能会出现这种情况。加上您反复设置的目标组的数字。 (类似于
update top (50) #temptable set targetgroup = 1 where targetgroup is null and somecriteria = 123 order by sortkey、update top (50) #temptable set targetgroup = 2 where targetgroup is null and othercriteria = 456 order by sortkey等)
标签: sql sql-server sorting random discrete-mathematics