Альтернатива для просмотра сложных данных? - PullRequest
0 голосов
/ 14 декабря 2010

У меня есть таблица, которая содержит частичные данные, которые бесполезны для пользователя, просматривающего мое приложение. Зритель хочет увидеть похожую таблицу, в которой рассчитаны все значения, и хочет иметь возможность быстро запрашивать эти данные. Обычно это было бы идеальным местом для использования View. К сожалению, сложный характер расчетов ограничивает мое использование Views, поэтому мне нужно альтернативное решение. Я думал о том, чтобы сделать что-то вроде следующего ...

Таблица A содержит внутренние данные. Каждый раз, когда эта таблица обновляется, запускается триггер, который обновляет Таблицу B, которая показывает результат этих вычислений. В этот момент можно быстро запросить таблицу B.

Мое единственное беспокойство заключается в том, что процедура расчета является несколько длительной, и таблица A может многократно обновляться пакетами. Существуют ли решения, которые похожи на триггер «До выбора»? Таким образом, в основном таблица A может обновляться много раз подряд, но вычисление будет происходить только при запросе к таблице B?

Вот пример временной шкалы:

  1. Таблица A обновлена ​​
  2. Таблица A снова обновлена ​​[Не запускать SP, поскольку данные Таблицы B пока никому не нужны]
  3. Данные запрашиваются из таблицы B [Запустите SP, чтобы обновить таблицу B перед получением данных]
  4. Таблица A обновлена ​​
  5. Данные запрашиваются из таблицы B [Запустите SP, чтобы обновить таблицу B перед получением данных]
  6. Данные запрашиваются из таблицы B [Не запускать хранимую процедуру, поскольку таблица A не обновлялась между запросами данных таблицы B]

Итак, мои вопросы:

  1. Существует ли что-либо подобное тому, что я описал выше?
  2. Если нет, есть ли способ удержать триггеры до завершения пакета обновлений / вставок? Таблица А не будет изменяться очень часто, поэтому я могу жить с медленным триггером, когда он обновляется. Единственная проблема состоит в том, что, когда таблица A обновляется , обычно это сотни строк одновременно, и я не хочу, чтобы медленный триггер запускался каждый раз.

Спасибо за любые решения / понимание!

Редактировать - Немного подробнее о том, почему (я думаю, по крайней мере) реализация триггера будет медленной:

  1. Приложение, которое будет отправлять операторы Update / Insert / Delete, использует LINQ-to-SQL, что не особенно хорошо для пакетных операций. Так что, если бы я хотел удалить несколько записей, он бы отправил несколько операторов удаления вместо пакетного оператора удаления. Есть ли способ сгруппировать операторы удаления и запустить триггер после этого? (Может быть, я зашла слишком далеко от темы).
  2. «Вычисления», о которых я говорю, включают некоторые рекурсивные функции и некоторые процессы принятия решений. Данные, с которыми я на самом деле имею дело, это планирование данных. Таким образом, таблица A содержит задачи, которые могут иметь или не иметь запланированное начало. Если запланированный запуск не определен, он должен извлечь его из запланированного запуска предшественников + его продолжительности предшественников. В некоторых случаях предшественник может не иметь этой информации, следовательно, рекурсивный запрос, который продолжает копаться, пока не найдет результат. Он не слишком медленный, но если бы он запускался при каждой вставке / обновлении / удалении, он бы туда попал. «Таблица B», на которую я ссылаюсь выше, в основном та же самая таблица, но она уже содержит рассчитанные данные запланированного запуска (которые необходимо изменить при обновлении таблицы A).

Ответы [ 4 ]

2 голосов
/ 14 декабря 2010

Я бы подумал, что материализованное представление сможет решить эту проблему и работать довольно быстро.Однако ОП не говорит, что такое «расчеты», а лишь в том, что они работают медленно.В результате вот вам лучший вариант:

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

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

дает доступ к «запросу» только через вызов хранимой процедуры, в этой процедуре запускается обработка, используемая заданием(удостоверится, что данные в таблице B обновлены), тогда он выполнит запрос, используя таблицу B.

2 голосов
/ 14 декабря 2010

Триггеры работают со всей партией записей, которые вставляются или обновляются, а не по одной строке за раз.

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

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

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

Дайте нам пример расчета и потенциального триггера, и мы сможем вам лучше помочь.

Невозможно сгруппировать группу, если отдельные транзакции выполняются в одном групповом триггере. Возможно, вам следует прекратить использовать LINQ для этого и отправлять сообщения, если вам нужны пакеты для совместной обработки. Операции на основе множества обычно предпочтительнее, если вы работаете с несколькими записями одновременно.

0 голосов
/ 15 декабря 2010

Это более простая вариация того, что уже обсуждалось ...

Если у вас в обеих таблицах есть столбцы DeltaTs / EditTs, вы можете:

Возвращает данные запроса с помощью хранимой процедуры, которая проверяет max (Deltats) и max (deltats) в обеих таблицах и обновляет таблицу b при необходимости. В первый раз, когда вы выберете после обновления таблицы A, вы получите небольшой удар, но потом все будет хорошо и быстро.

0 голосов
/ 14 декабря 2010

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

...