Самый быстрый способ обработки миллионов строк в SQL Server для диаграммы - PullRequest
0 голосов
/ 30 ноября 2018

Мы регистрируем данные в реальном времени каждую секунду в базе данных SQL Server, и мы хотим генерировать диаграммы из 10 миллионов строк и более.На данный момент мы используем что-то вроде кода ниже.Цель состоит в том, чтобы получить как минимум 1000-2000 значений для перехода на график.

В приведенном ниже запросе мы берем среднее значение каждой следующей n-й строки в зависимости от количества данных, которые мы выбираем из LargeTable.Это прекрасно работает до 200 000 выбранных строк, но тогда это слишком медленно.

SELECT 
    AVG(X),
    AVG(Y)
FROM 
    (SELECT 
         X, Y,
         (Id / @AvgCount) AS [Group]
     FROM 
         [LargeTable]
     WHERE 
         Timestmp > @From
         AND Timestmp < @Till) j
GROUP BY
    [Group]
ORDER BY 
    X;

Теперь мы попытались выделить только каждую n-ю строку из LargeTable, а затем усреднить эти данныечтобы добиться большей производительности, но это занимает почти столько же времени.

SELECT 
    X, Y
FROM 
    (SELECT 
         X, Y,
         ROW_NUMBER() OVER (ORDER BY Id) AS rownr
     FROM 
         LargeTable
     WHERE 
         Timestmp >= @From
         AND Timestmp <= @Till) a
WHERE 
    a.rownr % (@count / 10000) = 0;

Это всего лишь псевдокод!У нас есть индексы для всех соответствующих столбцов.

Существуют ли лучшие и более быстрые способы получения данных диаграммы?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Я думаю о двух подходах к улучшению производительности диаграмм:

  1. Пытается улучшить производительность запросов.
  2. Сокращение объема данных, необходимых для чтения.

Мне практически невозможно улучшить производительность запросов без полного DDL и планов выполнения.Поэтому я предлагаю вам уменьшить объем данных, которые нужно прочитать.

Ключ сводится к суммированию групп с заданным уровнем детализации по мере поступления данных и хранению их в отдельной таблице, как показано ниже:

CREATE TABLE SummarizedData
(
   int GroupId PRIMARY KEY,
   FromDate datetime,
   ToDate datetime,
   SumX float,
   SumY float,
   GroupCount 
)

IdGroup должен быть равен Id/100 или Id/1000 в зависимости от того, сколько гранулярности вы хотите в группах.С большими группами вы получаете более грубую гранулярность, но более эффективные диаграммы.

Я предполагаю, что столбец LargeTable Id монотонно увеличивается, поэтому вы можете сохранить последний Id, который был обработан в другой таблице с именемSummaryProcessExecutions

Вам потребуется хранимая процедура ExecuteSummaryProcess, которая:

  1. Чтение LastProcessedId из SummaryProcessExecutions
  2. Чтение Last Id на большой таблицеи сохранить его в @NewLastProcessedId переменную
  3. Суммировать все строки из LargeTable с Id > @LastProcessedId and Id <= @NewLastProcessedId и сохранить результаты в SummarizedData таблицу
  4. Сохранить @NewLastProcessedId переменную в SummaryProcessExecutions таблицу

Вы можете часто выполнять ExecuteSummaryProcess хранимую процедуру в задании агента SQL Server.

Я считаю, что группировка по дате была бы лучшим выбором, чем группировка по идентификатору.Это упростит вещи.Столбец SummarizedData GroupId не будет связан с LargeTable Id, и вам не нужно будет обновлять SummarizedData строки, вам нужно будет только вставить строки.

0 голосов
/ 30 ноября 2018

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

CREATE NONCLUSTERED INDEX [IDX_Timestmp] ON [LargeTable](Timestmp) INCLUDE(X, Y, Id)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...