将数据分成20个大致相等的SQL Server分区

时间:2016-12-23 22:37:18

标签: sql sql-server partitioning

我有来自某个来源的大量数据,每条记录的维度为dim1。 Dim1最多可以有100万个唯一值。其中一些将拥有大量数据,而另一些则会减少。对于例如Dim1value1可能有100K记录,Dim1value2可能有100万条记录,Dim1value3可能有10条记录,依此类推。

现在我想将它们分成几个相同的分区,因此与每个Dim1相关的数据进入一个组,我想创建大约20个有些相等的组。

基本上每个具有Dim1Value1的记录都应该进入一个组,依此类推。 这是一个脚本,显示了ntile如何不这样做。

IF OBJECT_ID('tempdb.dbo.#t') IS NOT NULL
    DROP TABLE #t

CREATE TABLE #t
(
    Dim1 varchar(100),
    numberofrecs int
)

DECLARE @counter int = 1

WHILE(@counter < = 100)
BEGIN
    INSERT #t
        SELECT 
            'Dim1value' + CAST(@counter AS VARCHAR(10)), 
            CAST(RAND()  * 100 AS INT)

    SET @counter = @counter + 1
END

SELECT * FROM #t

SELECT 
    NTILE(5) OVER(order by numberofrecs),
    Dim1, * 
FROM #t

1 个答案:

答案 0 :(得分:0)

分割dim1的最简单方法是:

SELECT ROWNUMBER()OVER(按numberofrecs排序)%20 + 1 AS PartNr, DIM1, * 从T ORDER BY 1

这不是一个完美的算法,它只是通过使用模数函数按记录数和伪分区排序来近似组​​。对于更好的算法,使用面向对象的逻辑而不是关系方法来实现CLR存储过程是有意义的。另一种方法是让ETL过程分析您的数据并选择正确的分区。

我相信你误解了分区的概念。虽然您应该为分区选择群集,但尝试尽可能在分区上平均分割数据,但在实际环境中分区数量不是常量值。分区的整个目的是优化数据存储,dml和查询。您可能还想实现一个滑动窗口,但这对您的方法来说非常复杂且不直观。 dim1中的数据是否固定且不可更改?如果是这样,您可以选择您考虑的方法。如果没有,您需要找到适合群集到分区的索引。例如,日期值可以是候选者,并将该日期分为几周,几天或几年左右。