#sql-server #tsql
#sql-server #tsql
Вопрос:
Можно ли использовать подсказку соединения с перекрестным соединением в T-SQL? Если да, то каков синтаксис?
select *
from tableA
cross ? join tableB
Комментарии:
1. Обе таблицы будут сканироваться полностью, поэтому я подозреваю, что любая подсказка, которую вы дадите, повлияет на производительность. Почему вы хотите дать подсказку здесь? Я чувствую проблему XY .
2. @Larnu Я пытаюсь исправить свой план выполнения, мои предполагаемые строки сильно отклоняются от вложенного объединения циклов. Я изменил курсор на перекрестное соединение… Теперь код работает быстрее с перекрестным соединением, но я хочу сделать его еще быстрее. Итак, я просто хочу поэкспериментировать с подсказкой соединения… Все предикаты являются функциональными, поэтому я думаю, что это влияет на статистику…
3. Если оценки неверны, я бы предположил, что статистика устарела. Определенно проблема XY.
4. Для уточнения специфики обслуживания индексов вам лучше обратиться к администраторам баз данных .
5. Короткий ответ — нет, согласно документам . Если вы обнаружите, что a
CROSS JOIN
внутренне переписано для использования другого типа соединения (что может легко произойти при добавлении условий), и вы хотите намекнуть на это (несмотря на то, что подсказки соединения являются последним средством), перепишите запрос самостоятельно, чтобы он соответствовал плану выполнения. Если это не вариант, вам придется возиться с такими вещами, как планы принудительного выполнения, что совсем не весело. Рассмотрите хранилище запросов для такого рода работы (QS — отличный инструмент в целом, там, где он доступен).
Ответ №1:
На основе ваших комментариев
Я пытаюсь исправить свой план выполнения, мои предполагаемые строки сильно отклоняются от вложенного объединения циклов. Я изменил курсор на перекрестное соединение… Теперь код работает быстрее с перекрестным соединением, но я хочу сделать его еще быстрее. Итак, я просто хочу поэкспериментировать с подсказкой соединения…
У меня 900 из 2000000 как фактических, так и оценочных для соединения с вложенным циклом..И я думаю, что это шаг, на котором происходит перекрестное соединение…
это таблица из ETL, поэтому каждый день появляется много новых данных..
У меня есть несколько предложений
- Не переходите сразу к перекрестному соединению. Если он выполняет соединение с вложенным циклом из-за действительно плохой оценки мощности, попробуйте вместо этого использовать подсказку хэш-соединения
- Это определенно может помочь обновить статистику (для получения информации изучите «Проблему с восходящим ключом»). Однако вы можете проверить, настроена ли ваша статистика на автоматическое обновление и запускается ли она (например, после ETL, просмотрите свойства статистики, чтобы узнать, когда они были обновлены в последний раз и т. Д.)
- Попробуйте исправить неверную оценку мощности. Один из способов — разделить большие задачи на более мелкие задачи (например, на временные таблицы).
- Если вы используете табличные переменные (например, DECLARE @temptable TABLE ), а не временные таблицы (например, CREATE TABLE #TempTable ), остановите его. Переменные (включая табличные переменные) не имеют статистики. Более старые версии часто предполагают 1 строку в табличных переменных. В SQL Server 2019 (пока вы находитесь в последнем режиме совместимости) внесены некоторые изменения, но все еще есть некоторые большие проблемы.
Когда вы сводите все к одной операции, которая имеет плохую оценку мощности, вы также можете делать такие вещи, как добавление индексов / etc, чтобы помочь с этой оценкой (помните — вы можете поместить индексы и первичные ключи во временные таблицы — они также могут ускорить обработку, если к таблице обращаются несколько раз).
Комментарии:
1. Спасибо, но у меня есть перекрестное соединение, потому что я удалил курсор, а переменная курсора использовалась в условии соединения.. Поэтому я могу комбинировать таблицы только с перекрестным соединением, а затем, когда другие таблицы объединяются, я фильтрую… Существует 4 объединения (таблицы), и я фильтрую их последние на основе другой таблицы.. Я попытаюсь создать временную таблицу..
2. Спасибо за галочку! Обратите внимание, что временная таблица помогает с оценками мощности. Если вы обнаружите (например), что первая часть запроса содержит действительно неправильные данные, вы можете вместо этого сохранить это во временной таблице, а затем выполнить вторую часть запроса, используя временную таблицу, которая, надеюсь, получит лучшие оценки. Однако при использовании этой стратегии вам действительно нужно сосредоточиться на том, чтобы размер данных был как можно меньше (например, не соединяйте 2 миллиона строк и 1 миллион строк и не храните их во временной таблице).
3. 5 таблиц слишком переплетены и слишком разделены. Существуют скалярные UDF, которые используют столбцы из разных таблиц в select…. Возможно, я могу удалить одну таблицу, но я не думаю, что это стоит усилий…
4. Я посмотрю, что я могу сделать… Спасибо за помощь… Я думаю, что следующая таблица временных запросов будет полезной…
5. Обратите внимание, что скалярные функции также имеют проблемы — например, см. Мнение Брента Озара о них . Возможно, вы захотите переписать эту часть.