2009-09-21 2 views
0

У меня есть таблица, которая поддерживает данные о производительности системы, каждая запись - это вызов, сделанный для некоторого важного метода, и состоит из имени метода, его продолжительности и знак - каждый запрос к системе присваивается уникальный маркер и так все записей с тем же самым таким же запросом, например:«Индексирование» (также поддерживающая таблицу) совокупных данных в SQL Server 2005

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 

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

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

Что мне действительно нужно здесь является «Индекс» на SUM (Продолжительность), сгруппированных по токена, то есть таблица, где я могу сделать что-то вроде:

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

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

+0

В некоторых случаях индексированные представления полезны. –

+0

Я задавался вопросом, что, однако, индексированные представления не могут использовать большинство (возможно, всех) совокупных функций (MAX, AVG и т. Д.) - http://www.sqlteam.com/article/indexed-views-in- sql-server-2000 – Justin

ответ

3

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

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

+0

Большое спасибо, я не понял, что для индексированных представлений есть сводные функции подстановки. – Justin

+0

Я закончил сортировку с помощью комбинации индексированных представлений и таблиц агрегированных данных, поддерживаемых с помощью триггеров и запланированных заданий. – Justin

0

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

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

+0

Значение токена достаточно, если мне нужен только 1 токен, однако я хочу запросить на основе агрегированных значений на всех токенах, а именно: я хочу, чтобы верхние несколько токенов сортировались по совокупному значению. Обычно для этого требуется сканирование таблицы, поскольку SQL-сервер должен вычислять агрегированное значение для всех токенов, прежде чем он сможет их сортировать. – Justin

0

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

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

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

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

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