У меня одинаковые вычисления в предложениях SELECT и GROUP BY. Действительно ли SQL-сервер выполняет эти вычисления дважды, или он достаточно умен, чтобы делать это только один раз?
Простой ответ заключается в том, что SQL Server не дает общих гарантий относительно того, когда и сколько раз скалярное выражение будет оцениваться во время выполнения.
В оптимизаторе и механизме исполнения есть все виды сложных (и недокументированных) поведений, касающихся размещения, выполнения и кэширования скалярных выражений. Книгам онлайн не нужно много говорить об этом, но то , что он говорит , это:
Это описывает одно из поведений, на которое я ссылался ранее, отложенное выполнение выражений. Я написал о некоторых других текущих поведениях (которые могли измениться в любое время) в этом сообщении в блоге .
Другое соображение заключается в том, что модель затрат, используемая оптимизатором запросов , в настоящее время мало что делает для оценки стоимости скалярных выражений. Без надежной структуры затрат текущие результаты основаны на широкой эвристике или чистой случайности.
Для очень простых выражений, вероятно, не имеет большого значения, вычисляется ли выражение один или несколько раз в большинстве случаев. Тем не менее, я столкнулся с большими запросами, где производительность снижалась, когда выражение избыточно оценивалось очень много раз, или когда оценка выполнялась в одном потоке, где было бы выгодно оценивать параллельную ветвь выполнения. план.
Таким образом, текущее поведение не определено, и в планах выполнения ничего особенного нет, чтобы помочь вам выяснить, что произошло (и не всегда будет удобно подключать отладчик для изучения подробного поведения движка, как в сообщении в блоге).
Если вы сталкиваетесь со случаями, когда проблемы скалярной оценки влияют на производительность, поднимите проблему с помощью службы поддержки Microsoft. Это лучший способ предоставить обратную связь для улучшения будущих версий продукта.
cross apply
в этом случае немного растянуто, и это, скорее всего, повредит производительности, введя ненужное самостоятельное соединение.CROSS APPLY
Просто определяет псевдоним из столбцов в одной и той же строке. Нет необходимости в соединении. напримерSELECT COUNT(*), hilo FROM master..spt_values CROSS APPLY (VALUES(high + low)) V(hilo) GROUP BY hilo
Производительность - это только один аспект. Другое дело в ремонтопригодности.
Лично я склонен делать следующее:
ОБНОВИТЬ:
Если вы не любите делать вложения, вы можете создать VIEW для каждой таблицы, где вам нужно использовать сложные выражения.
Тогда вы могли бы делать выборку без дополнительных вложений;
источник