Почему индексированные представления не могут иметь агрегат MAX ()?

Я пробовал несколько представлений индекса и впечатлен, но мне почти всегда нужны максимальные или минимальные значения, и я не могу понять, почему это не работает с ними, может ли кто-нибудь объяснить, почему?

Я ЗНАЮ, что им нельзя, просто не могу понять почему !!! Подсчет и т. Д. Разрешен, почему не МИН / МАКС, я ищу объяснение ...


person alex    schedule 25.01.2010    source источник


Ответы (4)


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

Некоторые агрегаты, такие как COUNT_BIG() или SUM(), можно пересчитать, просто посмотрев на измененные данные. Они разрешены в индексированном представлении, потому что, если базовое значение изменяется, влияние этого изменения может быть вычислено напрямую.

Другие агрегаты, такие как MIN() и MAX(), нельзя пересчитать, просто глядя на изменяемые данные. Если вы удалите значение, которое в настоящее время является максимальным или минимальным, тогда необходимо будет найти новое максимальное или минимальное значение во всей всей таблице.

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

person Remus Rusanu    schedule 25.01.2010
comment
Их можно было бы поддержать, если бы вы ограничили таблицу, чтобы разрешить только insert операции, а не update или delete. (Если бы вы хотели сделать одно из них, вам пришлось бы отбросить индексированное представление и затем воссоздать его.) Довольно много таблиц предназначены для практического использования только для вставки, и для них будет полезен способ ускорения запросов max и min. . - person Ed Avis; 10.05.2017
comment
Фактически измененная строка могла сравниваться только с результатом кэшированных данных, выбирая максимальное значение для MAX и минимальное для MIN. Почему они этого не делают? - person Iúri dos Anjos; 28.04.2018
comment
@ Iúri dos Anjos Потому что тогда, если вы обновите строку, которая раньше была MAX, и уменьшите ее, ей все равно придется сканировать всю остальную часть таблицы в поисках более низких значений. Итак, вы задаетесь вопросом: «ПОЧЕМУ Я НЕ ДОЛЖЕН РЕШИТЬ !!» Я предполагаю, что это сводится к гарантированной производительности, когда разрешенные операции работают только с этой единственной строкой, и если вы разрешили запускать MAX, он мог бы сканировать миллион строк каждый раз, когда была сделана вставка. Но это определенно неприятно, если вы ожидаете, что значение MAX будет только увеличиваться (как для моих данных) - person Simon_Weaver; 15.11.2018
comment
Я немного запутался в AVG. Поскольку поддерживаются Count_BIG и SUM, почему не AVG? Повторное сканирование не требуется. - person Haijin; 07.01.2019
comment
@Haijin хороший вопрос, и я не уверен в ответе. Думаю, что-то касается NULL обработки ... - person Remus Rusanu; 07.01.2019
comment
Вы можете создать свой собственный AVG, сохранив сумму и итоговую сумму SUM(CatsQty) AS TotalCats, COUNT_BIG(*) AS TotalCount отдельно и мгновенно вычислив ее в своем SELECT с помощью SELECT TotalCats / TotalCount AS AverageCatsQty FROM AnimalsView. Конечно, это только СРЕДНЕЕ среднее. - person Simon_Weaver; 21.04.2021

Агрегатные функции, такие как MIN / MAX, не поддерживаются в индексированных представлениях. Вы должны указать MIN / MAX в запросе, окружающем представление.

Существует полное определение того, что разрешено, а что запрещено в индексированном представлении здесь (SQL 2005).
Цитата:

Агрегатные функции AVG, MAX, MIN, STDEV, STDEVP, VAR или VARP. Если в запросах, ссылающихся на индексированное представление, указано AVG (выражение), оптимизатор может часто вычислять необходимый результат, если список выбора представления содержит SUM (выражение) и COUNT_BIG (выражение). Например, список SELECT индексированного представления не может содержать выражение AVG (column1). Если список SELECT представления содержит выражения SUM (column1) и COUNT_BIG (column1), SQL Server может вычислить среднее значение для запроса, который ссылается на представление и указывает AVG (column1).

person AdaTheDev    schedule 25.01.2010

Помимо причин, указанных Ремусом, меньше практической необходимости поддерживать MIN и MAX. В отличие от COUNT () или SUM (), MAX и MIN вычисляются быстро - все устанавливается после одного поиска; вам не нужно читать много данных.

person A-K    schedule 16.02.2012
comment
Вероятно, у кого-то была веская причина нуждаться в MIN или MAX. Я нашел этот вопрос, когда искал способ создать именно такой индекс, так как запрос займет от минут до секунд. Ведение его вручную кажется единственным решением, но мне это не особенно нравится ... - person jmoreno; 08.08.2014
comment
Уточню :-) У вас это задом наперед. Дело в том, что ПЕРВОНАЧАЛЬНО при создании индекса все COUNT, SUM, MAX и MIN просты и занимают одно и то же время. Но когда вы добавляете, удаляете или обновляете строку, все необходимо пересчитывать. Таким образом, для COUNT, если вы удалили, вы просто вычитаете единицу, для SUM, если вы добавляете строку, вам просто нужно ДОБАВИТЬ значение соответствующей строки к «промежуточной сумме». Однако для MAX и MIN вам ВСЕГДА потребуется сканирование, если вновь вставленное или измененное значение находится ВНУТРИ текущего диапазона от MIN до MAX. Это могут быть миллионы записей, которые могут быть заблокированы. и т. д. и т. д. - person Simon_Weaver; 15.11.2018
comment
Также я не уверен, что вы имеете в виду под «менее практической потребностью». Являются ли они общими, необходимыми или нет, полностью зависит от того, что представляют собой ваши данные. - person Simon_Weaver; 15.11.2018
comment
@Simon_Weaver ... это правда лишь отчасти. Если вы добавляете строку, вы можете сравнить текущее значение с сохраненным минимумом / максимумом, поскольку предыдущие записи детерминированы с текущим сохраненным значением. Если вы удаляете строку, вам нужно только пересчитать все, если ваше текущее значение равно текущему минимальному или максимальному значению. случай добавления не имеет эффективного отличия от счетчика / суммы, а строка удаления имеет довольно ограниченный шанс оказать влияние. - person Matthew Whited; 05.12.2020

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

id = row_number() over (order by col1, col2) 
person Vernard Sloggett    schedule 17.10.2019