#sql #sql-server #tsql #sql-server-2012 #dynamics-crm-2013
#sql #sql-сервер #tsql #sql-server-2012 #динамика-crm-2013
Вопрос:
Что быстрее?
update c
set
c.createdon=q.CreatedOn
,c.createdby=case when q.createdby is not null then q.createdby end
,c.modifiedon=q.modifiedon
,c.modifiedby=case when q.ModifiedBy is not null then q.ModifiedBy end
from crm_annotationbase c
join IncidentWorknote q
on c.annotationid=q.annotationid
или это:
update c
set
c.createdon=q.CreatedOn
,c.createdby=isnull(q.createdby,c.createdby)
,c.modifiedon=q.modifiedon
,c.modifiedby=isnull(q.modifiedby,c.modifiedby)
from crm_annotationbase c
join IncidentWorknote q
on c.annotationid=q.annotationid
У меня первый запрос выполняется уже 24 часа. Я обновляю таблицу CRM 2013 на основе промежуточных данных.
Я хотел бы знать, выбрал ли я наиболее эффективное решение для этого?
Комментарии:
1. Если вы хотите оптимизировать 24-часовой запрос для выполнения значительно быстрее, проверка null — это последнее, на что я бы обратил внимание. На самом деле это просто выбор произвольного элемента этого запроса и обвинение его в проблемах с производительностью.
2. В этой статье подробно описывается производительность между COALESCE и ISNULL. ОБЪЕДИНЕНИЕ — это, по сути, скрытый СЛУЧАЙ. sqlmag.com/t-sql/coalesce-vs-isnull
3. Согласитесь с приведенными выше утверждениями, почему бы не ускорить его, выполнив where q.modifiedon >= GetDate() -1
4. Вы постоянно обновляете все записи, вам нужно обновлять только те, которые были изменены. Я предположил, что вы запускаете его ежедневно. Вы можете относительно легко ограничить обновляемые записи.
5. @MikeMiller большое спасибо. но я не знаю, как определить, изменилась ли запись. мне нужно запустить этот процесс только один раз.
Ответ №1:
Хорошо .. Мне пришлось покопаться в этом скрипте. Судя по комментариям, это очень большая таблица, которую вы пытаетесь обновить. ЛУЧШИЙ способ ускорить это обновление — разбить его на пакеты. Причина, по которой это занимает так много времени, заключается в транзакционном характере системы… Если что-то не удается, ВСЯ транзакция (все ваше обновление) будет отменена. Это занимает ОООЧЕНЬ много дополнительного времени. Если вам НЕ нужна эта транзакционная схема «все или ничего», попробуйте что-то вроде этого (ниже). Нам нужно обновить сотни миллионов записей, и мы смогли ускорить это на НЕСКОЛЬКО ЧАСОВ, просто выполнив пакетное обновление.
Настройка этого может ускорить работу на основе ваших данных.
DECLARE @Update INT
DECLARE @Batch INT
-- Total number of records in database
SELECT @Update = (
SELECT COUNT(id)
FROM [table] WITH (NOLOCK) -- be CAREFUL with this
WHERE [' @fName '] IS NOT NULL) --optional
SELECT @Batch = 4000 --Batch update amount
WHILE (@Update > 0)
BEGIN
UPDATE TOP(@Batch) c
set
c.createdon=q.CreatedOn
,c.createdby=case when q.createdby is not null then q.createdby end
,c.modifiedon=q.modifiedon
,c.modifiedby=case when q.ModifiedBy is not null then q.ModifiedBy end
from crm_annotationbase c
join IncidentWorknote q
on c.annotationid=q.annotationid
SELECT @Update = @Update - @Batch; -- Reduce for next set
WAITFOR DELAY '000:00:00.400'; -- Allows for waiting transactions to process optional
END;
Комментарии:
1. Кроме того, это было бы быстрее, если бы annotationId был первичным ключом. Вы могли бы добавить оператор where типа «Где annotationId находится между @minBatch и @maxBatch» или что-то в этом роде. 🙂
2. Да.. Это то, что сработало для нас быстрее всего. Вы могли бы попробовать запустить его в более высоких пакетах. Но убедитесь, что логика верна перед запуском в производство (очевидно). TOP сработал для нас, потому что я ограничиваю обновление с помощью оператора WHERE, чтобы при обновлении четырех тысяч записей они больше не были в ВЕРХНЕЙ группе (потому что условие не выполняется).
Ответ №2:
То, что вы делаете, неправильно по двум причинам:
- Прямое обновление базы данных Dynamics CRM не поддерживается и может привести к ряду проблем с вашим экземпляром CRM (для обновления данных необходимо использовать веб-службы CRM)
CreatedOn
,CreatedBy
,ModifiedOn
иModifiedBy
являются системными полями, и они всегда заполняются, они никогда не содержат нулевых значений. (в частностиCreatedOn
, иCreatedBy
указываются при создании записи и не могут быть изменены после,ModifiedOn
иModifiedBy
обновляются при каждом обновлении записи)
Как советует Microsoft здесь: http://msdn.microsoft.com/en-us/library/gg328350.aspx#Unsupported
Неподдерживаемые настройки
Изменения данных (записи) в базе данных Microsoft Dynamics CRM с использованием команд SQL или любой технологии, отличной от описанной в Microsoft Dynamics CRM SDK.
Комментарии:
1. 1. пожалуйста, покажите мне источник, в котором говорится, что эти конкретные поля опасно обновлять вручную. я говорил об этом с MVP CRM, и он сказал, что все в порядке.
2. 2. правильно, но я проверяю наличие нулевых значений в промежуточной базе данных, а не в crm
3. вы обновляете базу данных CRM или нет? Я не могу поверить, что MVP CRM сказал, что это нормально для непосредственного обновления базы данных CRM.