Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Тоу Д. -> "Настройка SQL. Для профессионалов" -> 137

Настройка SQL. Для профессионалов - Тоу Д.

Тоу Д. Настройка SQL. Для профессионалов — СПб.: Питер, 2004. — 333 c.
ISBN 5-94723-959-0
Скачать (прямая ссылка): nastroykasqldlyaprof2004.djvu
Предыдущая << 1 .. 131 132 133 134 135 136 < 137 > 138 139 140 141 142 143 .. 161 >> Следующая


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

Таким образом, даже если такой кэш используется один раз, чтобы выполнить единственную задачу одного конечного пользователя, он может стоить меньше, чем повторяющиеся запросы, которые он делает ненужными. А если
Когда очень быстро — это еще недостаточно быстро

279

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

Объединенные запросы

Слепой запрос, считывающий все строки, которые потенциально может затронуть повторяющийся запрос, может быть слишком дорогим, и результирующий набор может оказаться слишком большим, чтобы его кэшировать. Однако это не препятствует тому, чтобы приложение объединяло несколько запросов в один запрос в той или другой форме. В нашем примере каждый проход по циклу приносит очередное значение Product_ID, на базе которого выполняется исходный повторяющийся запрос. Можно выполнять циклы и без запросов, а просто создать список идентификаторов, чтобы использовать их в одном объединенном запросе. Например, запрос может принимать такие формы:

SELECT Product_Price FROM Price_list WHERE Product_ID in (<длинный список ID>)

AND Effective_Date <= : today

ORDER BY Product_ID ASC. Effective_Date DESC;

или

SELECT Product_Price FROM Price_List

WHERE Product_ID in ^подзапрос. возвращающий длинный список ID>)

AND Effective_Date <= : today

DRDER BY Product_ID ASC. Effective_Date DESC:

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

Слияние повторяющихся запросов с предыдущим запросом

Обычно источником значений параметров в повторяющихся запросах является предыдущий запрос. В нашем примере значение параметра : today скорее всего поступает из часов или календаря, но значение параметра : 1 практически наверняка берется из предыдущего запроса, который вернул д линный список значений Product_ID. Самая вероятная причина появления повторяющегося запроса заключается в том, что мы пытаемся получить текущую (с самым недавним значением Effecti ve Date) цену продукта для каждой строки, возвращенной предыдущим запросом, для чего используем первую строку среди тех, которые этот запрос возвращает при каждом
280

10. Решения сложных проблем

выполнении. Так как цель запроса — найти подходящую строку с ценой для каждой строки предыдущего запроса, функционально он похож на соединение, но далеко не так эффективен.

Техника решения таких проблем заключается в попытке превратить запросы в реальные соединения. Когда эти повторяющиеся запросы — это простые запросы по первичному ключу, возвращающие одну строку, то преобразование в соединение очевидно. В таких случаях, как этот пример, решение сложнее. Запрос возвратил ценовую историю, отсортированную по Effecti ve_Date, чтобы поместить текущую эффективную цену в начале списка. Эта запись о текущей эффективной цене на самом деле единственная запись, которая нужна пользователю. Чтобы объединить этот повторяющийся запрос с другим запросом, возвращающим список ProductJD, вам нужно найти способ, как присоединить первую строку, возвращенную отсортированным запросом, не считывая остальные.

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

¦ Если строки никогда не создаются с будущими значениями Effecti ve_Date, создайте триггер, который устанавливает значение флага Current_Pri се_П ад равным ' N' для уже устаревших цен и создает новые цены со значением Current_Pri ce_Fl ag равным 'Y'.

¦ Если иногда создаются записи для будущих значений цены, каждую ночь запускайте пакетный процесс, который ищет будущие записи эффективных цен, только что ставших текущими, и обновляет эти записи, присваивая Current_Pri ce_Fl ag значение ' Y', одновременно изменяя значение поля Current_Pri ce_Fl ag для только что устаревших цен на ' N'. Этот ночной пакетный процесс будет, вероятно, дополнять обновления при помощи триггера новых записей цен, бывших текущими на время создания.
Предыдущая << 1 .. 131 132 133 134 135 136 < 137 > 138 139 140 141 142 143 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100