«Индексирование» (или ведение таблицы) агрегированных данных в SQL Server 2005 - PullRequest
0 голосов
/ 21 сентября 2009

У меня есть таблица, в которой хранятся данные о производительности системы, каждая запись является вызовом какого-либо важного метода и состоит из имени метода, его продолжительности и токена - каждому запросу к системе присваивается уникальный токен и т. Д. все записи с одним и тем же токеном относятся к одному и тому же запросу, например:

CallName    Duration    Token
----------- ----------- -----------
GetData     121         12345
Process     800         12345
SaveData    87          12345

GetData     97          ABCDE
Process     652         ABCDE
SaveData    101         ABCDE

Меня интересуют сводные данные, сгруппированные по токену и CallName, например:

-- The total duration of each request, in descending order
SELECT Token, SUM(Duration) FROM Requests GROUP BY Token ORDER BY SUM(Duration) DESC

-- The average duration of each call, in descending order
SELECT CallName, AVG(Duration) FROM Requests GROUP BY CallName ORDER BY AVG(Duration) DESC

Теперь эта таблица потенциально очень большая, и меня будут интересовать только несколько верхних записей каждого запроса, поэтому я реализовал разбиение на страницы для обоих этих запросов. Проблема в том, что, поскольку эти запросы включают агрегатные функции, SQL-сервер в любом случае завершает сканирование таблицы.

Наверняка у других людей была эта проблема раньше?

Что мне действительно нужно, так это «индекс» по сумме (длительности), сгруппированный по токену, то есть таблица, в которой я могу делать такие вещи, как:

SELECT Token, SumToken FROM RequestTokens ORDER BY SumToken DESC
  • Это действительно плохая идея?
  • Если так, есть ли лучший способ?
  • Каков наилучший способ сделать это? Будут ли срабатывать триггеры при INSERT / UPDATE / DELETE (где я обновляю статистические значения на основе старых значений и измененных данных) или мне лучше вручную обновлять мой «индекс» при обновлении этой таблицы?

Триггеры - лучшее решение, которое я придумал до сих пор, но я уже вижу, что это кошмар тупика / согласованности! : -S

Ответы [ 3 ]

3 голосов
/ 21 сентября 2009

Как насчет потенциально представления, основанного на агрегатах, возможно, даже индексированного представления. Я не очень много сделал с индексированными представлениями, но в этой статье рассказывается об их использовании со сложными агрегатами, такими как AVG (). Может быть, это приведет вас в правильном направлении.

http://msdn.microsoft.com/en-us/library/aa933148%28SQL.80%29.aspx

0 голосов
/ 22 сентября 2009

Я сделаю еще один удар в этот, теперь, когда я понимаю это лучше. Это не редкая проблема с отчетностью, которая приводит к решениям для хранилищ данных, например: вы можете просто добавить вторую таблицу, содержащую предварительно агрегированные данные? Это действительно денормализованные / избыточные данные ... но они кажутся ясными и четко определенными и служат потребностям бизнеса. Пара морщин на эту идею:

Если данные вводятся только один раз, можете ли вы изменить подпрограмму ввода данных, чтобы добавить агрегированную строку одновременно. Если со временем это произойдет, вам понадобится повторяющийся процесс, чтобы «подметать». Я избегаю триггеров по общему принципу; они могут помочь здесь, но они также могут связать вашу систему в зависимости от моделей использования и взаимосвязей данных.

Насколько актуальными должны быть данные? Могут ли агрегированные данные не синхронизироваться с подробными данными, и если да, то как долго? У вас может быть задание агента SQL, которое запускается каждый день / час / 5 минут для сканирования последних записей и обновления агрегированной таблицы. (Добавьте индексированный столбец «последний введенный», и эти обновления могут быть быстрыми.) Компромисс - это период времени, в течение которого ваши данные будут отключены. (Но в этом столбце даты и времени может быть указано «до конца», когда данные точны. Может быть, вы не сделаете агрегированные данные доступными после этого момента?)

Если данные не изменяются после их ввода (без обновлений, без удалений, без поздних строк), это может сработать, но если вам нужно поддерживать обновления во времени, и агрегированные данные изменяются если бы был доступен одновременно с вводом данных, это может быть кошмаром.

0 голосов
/ 21 сентября 2009

Прежде всего, не будет ли достаточным индекс для столбца Token? Таким образом, учитывая значение Token, оптимизатор SQL-запросов будет сканировать только ту часть индекса, которая содержит интересующую вас строку. Сделайте это кластеризованным индексом, и вы получите оптимальную производительность.

Далее, как узнать, какое значение токена вас интересует при агрегировании? В списке нет столбца datetime (или timestamp), и значения токена, по-видимому, назначаются случайным образом (в отличие от некоторой формы возрастающего значения), поэтому я предполагаю, что вы знаете значение токена, которое нужно агрегировать, прежде чем выполнить запрос - в какой индексации следует делать то, что вы хотите. Если значения неизвестны, но как-то возрастают, есть ряд тактик, которые вы можете использовать, чтобы сначала определить самые последние значения X-токенов, и как только вы получите эти / эти токены, вы вернетесь к частичному сканированию таблицы.

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