Как управлять 3,1 миллиарда строк данных?


14

В настоящее время мне поручено реализовать схему хранения для относительно большого объема данных. К данным в первую очередь будут обращаться, чтобы определить текущее data pointзначение, но я также обязан отслеживать историю последних шести месяцев для анализа и анализа данных.

Недавнее требование было добавлено для отслеживания значения min/ max/ sumза прошедший час.

ПРИМЕЧАНИЕ. В идеале я хотел бы рассмотреть вариант MongoDB, но мне нужно продемонстрировать, что я сначала исчерпал параметры SQL-Server.

Данные

В следующей таблице представлен основной источник данных (чаще всего запрашивается). Таблица будет иметь приблизительно пять миллионов строк. Изменения данных будут преимущественно UPDATEзаявлениями с очень редкими INSERTзаявлениями после начальной загрузки данных. Я решил кластеризовать данные, dataPointIdкак вы всегда будете выбирать all values for a given data point.

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)

Вторая таблица заметно больше - примерно 3,1 миллиарда строк (данные за последние шесть месяцев). Данные старше шести месяцев будут удалены; в остальном строго INSERTоператоры данных (~ 200 строк / сек, 720 000 строк / час, 17 миллионов строк / неделя).

// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
    [dataPointId] [int]            NOT NULL,
    [valueId]     [int]            NOT NULL,
    [timestamp]   [datetime]       NOT NULL,
    [value]       [decimal](18, 0) NOT NULL,
    [delta]       [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])

)

Ожидается, что эта таблица увеличится вдвое, так как число отслеживаемых значений точек данных увеличивается до 400 строк / сек (поэтому не может быть и речи о ~ 10 миллиардах).

Вопрос (ы) (да, я задаю более одного ... они тесно связаны).

В настоящее время я использую базу данных SQL-Server 2008 R2 Standard Edition. Я, скорее всего, расскажу об обновлении до Enterprise Edition, если смогу достичь желаемого уровня производительности с помощью табличных разделов (или MongoDB, если не удастся достичь требуемых уровней производительности с SQL-сервером). Я хотел бы, чтобы ваш вклад в следующее:


1) Учитывая , что мне нужно вычислить min, maxи sumза последний час (как в now - 60 minutes). Каков наилучший подход для отслеживания последних данных:

  • Храните последние данные в памяти службы данных. Запишите вычисленные мин / макс / среднее с каждым обновлением данных.

  • Запросите недавнюю историю из таблицы истории (влияет на следующий вопрос?) Во время каждого оператора UPDATE. Запрос будет получать доступ к последним данным для значения точки данных и должен сканировать только последние миллионы записей или около того?

  • Сохранить недавнюю историю в самой строке DataPointValue, чтобы избежать поиска в таблице истории? Возможно, хранится в виде строки с разделителями и обрабатывается внутри процедуры UPDATE?

  • Другой вариант я не рассматривал?


2) Для DataPointValueHistoryзапросов к данным всегда будет dataPointIdодин или несколько запросов valueId. Запрашиваемые данные обычно относятся к последнему дню, неделе или месяцу, но в некоторых случаях могут быть полными шестью месяцами.

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

  • Кластер DataPointValueHistoryпо dataPointId -> valueId -> TIMESTAMP

  • Кластер DataPointValueHistoryпо timeStamp -> dataPointId -> valueId


3) Наконец, как уже упоминалось выше, я думаю, что будет иметь смысл разделить DataPointValueHistoryтаблицу. Будем весьма благодарны за любые предложения о том, как лучше разделить исторические данные.

  • Если сначала кластеризовать по метке времени, я думаю, что данные должны быть разбиты по неделям (всего 27 секций). Самый старый раздел будет очищен после 27 недели.

  • Если сначала кластеризовать dataPointId, я думаю, что данные должны быть разделены по некоторому модулю идентификатора?

Поскольку у меня очень ограниченный опыт работы с разделами таблиц, ваш опыт был бы оценен.


Вы удалили версию этого вопроса в StackOverflow?
Тарын

@bluefeet - Да, он был помечен как не по теме ... поэтому я удалил вопрос SO и заново создал его здесь (вероятно, я должен был дождаться его переноса).
Калгари Кодер

Нет проблем, я просто убедился, что у нас не было перекрестных вопросов.
Тарын

В Standard Edition вы все еще можете разбивать данные, используя многораздельные представления и несколько базовых таблиц. Не уверен, что ты обдумал это.
Джон Зигель

@Jon - Да, я рассмотрел ручные разделы таблиц (этот конкретный выбор будет зависеть от того, есть ли лицензия Enterprise или нет ... если да, почему роль моя собственная).
Калгари Кодер

Ответы:


4

Я нашел этот анализ очень полезным, когда я занимался поиском решения для аналитики, в котором в одной таблице было бы миллиарды строк.

http://leiliweb.wordpress.com/2012/12/11/partitioned-table-and-index-strategies-using-sql-server-2008/


Спасибо за ссылку, безусловно, полезно ... какие-либо мысли по пункту 1 или 2?
Калгари Кодер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.