2016-12-23 2 views
0

У меня есть огромное количество данных, поступающих из источника, и каждая запись имеет размер dim1. Dim1 может иметь до 1 миллиона уникальных значений. У некоторых из них будет много данных, а у некоторых будет меньше. Напр. Dim1value1 может иметь 100K записей, Dim1value2 может иметь 1 миллион записей, Dim1value3 может иметь 10 записей и т. Д.Данные Partiton в 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-сервер? обновить теги и сохранить только соответствующего поставщика. – Dekel

+0

Если SQL Server считает NTile() https://msdn.microsoft.com/en-us/library/ms175126.aspx –

+0

Я не думаю, что это сделает ntile. Я это рассмотрел, но он просто сортирует меру и затем делит мое измерение на n количество групп. в основном он поместит все размеры, которые имеют наибольшее количество в той же группе. это не то, что я хочу ... этот sql-скрипт будет демонострировать его ... –

ответ

0

Самый простой способ разделить ваш DIM1 будет:

ВЫБОР ROWNUMBER() НАД (заказ по numberofrecs) 20% + 1 А.С. PartNr, Dim1, * ОТ #t ORDER BY 1

Этот ia не идеальный алгоритм, он будет просто аппроксимировать группы путем упорядочивания по количеству записей и псевдоразделения с использованием функции modulo. Для лучшего алгоритма было бы целесообразно реализовать хранимую процедуру CLR с использованием объектно-ориентированной логики вместо реляционного подхода. Другой способ состоял бы в том, чтобы процесс ETL анализировал ваши данные и выбрал правильный раздел.

Я считаю, что вы неправильно поняли концепцию разбиения. В то время как вы должны выбрать кластер для своего раздела, пытаясь разделить данные как можно больше по разделам, количество разделов не является постоянным значением в реальной среде. Вся цель разделения состоит в оптимизации хранения данных, dml и запросов. Возможно, вы также захотите реализовать скользящее окно, но это будет очень сложно и неинтуитивно с вашим подходом. Являются ли данные в вашем dim1 фиксированными и неизменными? Если это так, вы можете выбрать свой подход. Если нет, вам нужно найти индекс, который подходит для кластеризации в разделы. Например, значение даты может быть кандидатом и разбивать эту дату на недели, мобы или годы или около того.

+0

Я сделал что-то подобное. Моя проблема в том, что я почти ВСЕГДА буду запрашивать одно значение Dim1. И я не хочу бить за него несколько разделов. ANd, когда я запрашиваю определенное значение Dim1, я буду запрашивать много истории, поэтому разделение на день или неделю не имеет смысла. Если я делаю тупое разделение только значением Dim1, например. Dim1value1 до value100 переходит в 1, значение от 101 до 200 идет в 2 и т. Д., Я в конечном итоге получаю неравные разделы ... например, Dim1value1 может иметь больше записей, если вы добавите dim1value2 в значение200 все вместе ... –

Смежные вопросы