2013-07-23 3 views
2

У меня есть представление, которому необходимо присоединиться к конкатенированной колонке. Например;JOIN on concatenated performance performance

dbo.View1 INNER JOIN 
dbo.table2 ON dbo.View1.combinedcode = dbo.table2.code 

Внутри «View1» находится колонка, которая состоит из этого;

dbo.tableA.details + dbo.tableB.code AS combinedcode 

Выполнение соединения в этой колонке происходит очень медленно. Однако фактический «View1» работает очень быстро. Плохая производительность связана с соединением, и в любой из таблиц или представлений не так много строк. Кто-нибудь знает, почему это может быть?

Спасибо за понимание!

+0

ли вы * есть * выполнить ваш присоединиться на каскадных колоннах или мыслимо, что вступление в исходных столбцов в отдельности может дать тот же результат? – gvee

+0

К сожалению, я должен выполнить его на конкатенированной колонке. Кроме того, я не могу индексировать столбец nvarchar и не использовать подсказки в моем представлении, поскольку он дает мне «подсказки запросов не могут использоваться в плане запроса». – creatiive

ответ

3

Поскольку на combinedcode нет индекса, JOIN, скорее всего, приведет к полному «сканированию таблицы» для вычисления кода для каждой строки.

Если вы хотите ускорить работу, попробуйте сделать вид в indexed view с индексом на combinedcode, чтобы помочь присоединиться.

Другая альтернатива, в зависимости от вашей версии SQL-сервера, состоит в том, чтобы (как ответы Parado) создать временную таблицу для соединения, хотя она, как правило, менее эффективна, по крайней мере, для однократных запросов.

1

Попробуйте так:

select * 
into #TemTap 
from View1 
/*where conditions on view1*/ 

после этого Вы можете создать index на #TemTap.combinedcode и чем

dbo.#TemTap as View1 INNER JOIN dbo.table2 ON dbo.View1.combinedcode = 
dbo.table2.code 

Он часто работает для меня.

0

Причина в том, что оптимизатор не имеет информации о конкатенированном столбце, поэтому он не может выбрать разумный путь соединения. Мое предположение, если вы посмотрите на план выполнения, заключается в том, что соединение использует объединение «вложенного цикла». (Я искушаюсь добавить «страшно» к этому.)

Возможно, вы сможете исправить это, указав индекс на table2(code). Оптимизатор должен решить использовать этот индекс, обойти оптимизацию плохих соединений.

Вы также можете использовать подсказки запросов, чтобы принудительно использовать «хеш-соединение» или «объединение слиянием». Я часто делаю это чаще для сложных запросов, где изменения в данных могут влиять на план запроса. (Такие подсказки возникают, когда запрос, принимающий 2 минуты в течение года, решает взять часы, заполнить временную базу данных и умереть, когда закончится свободное место.) Вы можете сделать это, добавив OPTION (merge join, hash join) в конец запроса , Вы также можете явно выбрать тип соединения в предложении on.

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

+0

В нем говорится, что «подсказки запросов не могут использоваться в плане запроса». Также я не могу поместить индекс в столбец, потому что это столбец nvarchar (текстовый код): - / – creatiive

0

Использование SQL-функций - это то, где условие не рекомендуется. здесь вы используете concatenate, где условие (косвенно, но да). поэтому он выполняет конкатенацию для каждой строки, а затем сравнивает ее с другой таблицей.

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

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

увидеть ссылку для индексированных представлений http://msdn.microsoft.com/en-us/library/ms191432.aspx#Restrictions