2016-12-23 68 views
0

我有大量来自源的数据,每个记录都有一个维度dim1。 Dim1可以有多达一百万个唯一值。其中一些将有大量的数据,有些则会少一些。对于例如Dim1value1可能有100K条记录,Dim1value2可能有100万条记录,Dim1value3可能有10条记录等等。分区数据分成20个大致相等的SQL Server分区

现在我想将它们分组到一定程度相等的分区,以便与每个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 
+0

它是mysql还是sql-server?更新标签并仅保留相关供应商。 – Dekel

+0

如果SQL Server考虑NTile()https://msdn.microsoft.com/en-us/library/ms175126.aspx –

+0

我不认为ntile会这样做。我考虑过它,但它只是将度量分类,然后将我的维度分成n组。基本上它会把所有具有最高数字的维度放在同一组中。这不是我想要的...这个SQL脚本将demonostrate它... –

回答

0

分割您DIM1最简单的方法是:

SELECT ROWNUMBER()OVER(由numberofrecs顺序)%20 + 1 AS PartNr, DIM1, * FROM #T ORDER BY 1

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

我相信你误解了分区的概念。尽管您应该为分区选择群集,但试图尽可能在分区上尽可能多地拆分数据,但分区数量在真实环境中并不是一个常数值。分区的全部目的是优化数据存储,dml和查询。你也可能想要实现一个滑动窗口,但这对您的方法来说确实很复杂且不直观。 dim1中的数据是否已修复且不可更改?如果是这样,你可以选择你考虑的方法。如果没有,您需要找到适合分区的索引。例如,一个日期值可能是一个候选人,并将这个日期分成几周,几个月或几年左右。

+0

我做了类似的事情。我的问题是我几乎总是从Dim1的一个值中查询。我不想为它分配多个分区。当我查询Dim1的某个特定值时,我会查询很多历史记录,因此按天或周分区是没有意义的。如果我通过Dim1的值进行哑分区,例如Dim1value1到100的值为1,值101到200的值为2,依此类推,我将得到不相等的分区......如果将dim1value2与value200的值相加,则Dim1value1可能会有更多的记录数... –