AXForum  
Вернуться   AXForum > Microsoft Dynamics CRM > Dynamics CRM: Разработка
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.09.2018, 17:51   #1  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Update millions of records
Привет,

Написал скрипты по интеграции нескольких сущностей. Нужно с SQL вытянуть 5 милионов записей и потом обновить их в СРМ Online системе. В общем - сплошная боль, даже с балками перфоманс очень посредственный. Вытянуть за раз 5 тысяч, обновить 1 тысячу, как Вы живете с проектами в которых нужны такие массовые операции? Многопоточность не поможет ибо все запросы становяться в очередь, и все следующие запросы будут ждать выполнения. Как жить в таких условиях?

Результаты следующие:
- retrieve 5000 = 30 сек, итого только 8,3 часов чтобы вытянуть 5 млн записей
- update 1000 = ~2 минуты, итого только 83,33 часов для апдейта
- select from SQL by Id 5000 records == 10 минут (слабое место, оптимизирую)

Нет плагинов на сущности, + там еще операция назначения.

Последний раз редактировалось Ion; 02.09.2018 в 18:07.
Старый 02.09.2018, 17:55   #2  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Вот такой код, как бы его оптимизировать
X++:
        public void StartOneByOneProcesssing()
        {

            int queryCount = 5000;
            int pageNumber = 1;
            int recordCount = 1;
            Boolean hasRecords = true;

            PagingInfo pagingInfo = new PagingInfo();
            pagingInfo.Count = queryCount;
            pagingInfo.PageNumber = pageNumber;

            EntityCollection results = null;

            var requestWithResults = CreateExecuteMultipleRequest();
            Lead sfLead = null;

            while (hasRecords)
            {

                try
                {
                    // Retrieve the page.
                    swXrm.Start();
                    results = _xrmLeadService.GetByQueryExpression(GetQueryExpression(queryCount, pageNumber, results?.PagingCookie));
                    swXrm.Stop();

                    Console.WriteLine("Elapsed XRM ={0}", swXrm.Elapsed);

                    swXrm.Reset();


                    hasRecords = results?.Entities?.Count > 0;

                    if (results.Entities != null)
                    {
                        var ids = results.Entities.Select(e => e.GetAttributeValue<string>("new_sfdcid")).ToArray();

                        swOneBuOnekSql.Start();
                        var sfLeads = _sfleadService.GetLeads(ids);
                        swOneBuOnekSql.Stop();
                        Console.WriteLine("Elapsed SQL One By One ={0}", swOneBuOnekSql.Elapsed);
                        swOneBuOnekSql.Reset();

                        Console.WriteLine("Page cokie = {0}", results?.PagingCookie);

                        swBulkSql.Start();
                        foreach (var xrmLead in results.Entities)
                        {
                            try
                            {
                                var sfdcid = xrmLead.GetAttributeValue<string>("new_sfdcid");
                                sfLead = sfLeads.FirstOrDefault(e => e != null && e?.Id == sfdcid);
                                
                                if(sfLead != null)
                                {

                                    Entity updatedXrmLead = _leadMapping.Create(xrmLead, sfLead);

                                    UpdateRequest update = new UpdateRequest { Target = updatedXrmLead };
                                    requestWithResults.Requests.Add(update);
                                    _userService.AssignLead(sfLead, updatedXrmLead.Id, xrmLead.GetAttributeValue<EntityReference>("ownerid")?.Id);

                                } else
                                {
                                    _logger.WriteUpdateLog(new UpdateLog("lead", sfLead?.Email ?? xrmLead.GetAttributeValue<string>("emailaddress1"), "not found in sql", sfLead?.Id ?? xrmLead.GetAttributeValue<string>("new_sfdcid")));
                                }

                                if(requestWithResults.Requests.Count == 1000)
                                {
                                    Stopwatch OneThousandRecords = new Stopwatch();

                                    OneThousandRecords.Start();

                                    var responseWithResults = _xrmLeadService.ExecuteMultipleRequest(requestWithResults);
                                    OneThousandRecords.Stop();

                                    Console.WriteLine($"1000 processed in {OneThousandRecords.Elapsed}");

                                    //foreach (var responseItem in responseWithResults.Responses)
                                    //{

                                    //    // An error has occurred.
                                    //    if (responseItem.Fault != null)
                                    //        DisplayFault(requestWithResults.Requests[responseItem.RequestIndex],
                                    //            responseItem.RequestIndex, responseItem.Fault);
                                    //}
                                    requestWithResults.Requests.Clear();
                                }

                            }
                            catch (Exception ex)
                            {
                                var sb = ParseError(ex);
                               _logger.WriteErrorLog(new ErrorLog("lead", sfLead?.Email, sb.ToString(), sfLead?.Id));

                            }

                        }

                        recordCount += queryCount;
                    }
                    swOneBuOnekSql.Stop();

                    Console.WriteLine($"Fetching page  {pageNumber} and total leads processed {recordCount} in {swOneBuOnekSql.Elapsed}");
                    swOneBuOnekSql.Reset();

                    pageNumber++;
                }
                catch (Exception ex)
                {
                    hasRecords = false;
                    Console.WriteLine(ex.ToString());
                }
            }
            Console.WriteLine($"************** One by one processing of leads finished ****************");
        }
Старый 03.09.2018, 11:08   #3  
ZooY is offline
ZooY
Участник
Аватар для ZooY
 
379 / 46 (2) +++
Регистрация: 24.06.2008
Адрес: Россия, Москва
Цитата:
Сообщение от Ion Посмотреть сообщение
... как Вы живете с проектами в которых нужны такие массовые операции?..
Проекты, в которых нужны такие массовые операции хромают на обе архитектурные ноги...
__________________
Моё: Cайт - Код - Dynamics365 Tools
Старый 03.09.2018, 12:19   #4  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Цитата:
Сообщение от ZooY Посмотреть сообщение
Проекты, в которых нужны такие массовые операции хромают на обе архитектурные ноги...
Причём тут архитектура решения? Мы говорим о возможностях апи, а кейсы могут быть разными : например первичную заливку делала компания А, они неправильно залили часть данных, клиент решил исправить ситуацию через n времени и нанял компанию Б. И вот сотрудники Б сталкиваются с ограничениями в системе.
Понятное дело в большенстве случаев такой надобности нет, но в любом случае CRM online имеет очень много 'неудобств' для рядовых разработчиков из-за ограничений

Последний раз редактировалось Ion; 03.09.2018 в 12:30.
Старый 03.09.2018, 18:01   #5  
ZooY is offline
ZooY
Участник
Аватар для ZooY
 
379 / 46 (2) +++
Регистрация: 24.06.2008
Адрес: Россия, Москва
Косяки одних разработчиков, создающие проблемы другим разработчикам не являются ограничениями системы.
__________________
Моё: Cайт - Код - Dynamics365 Tools
Старый 03.09.2018, 18:25   #6  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Цитата:
Сообщение от ZooY Посмотреть сообщение
Косяки одних разработчиков, создающие проблемы другим разработчикам не являются ограничениями системы.
Я не хочу разводить холивар о возможностях системы при работе с большими объемами данных. Очевидно, что в онлайн решения много ограничений и это факт. Меня больше интересует можно ли увеличить batch size как раньше делали через UpdateAdvancedSettingsRequest, сейчас этот класс стал закрытым и в доках я не нашел ответа.
Как вариант написать майкрософт и попросить их это сделать
Старый 03.09.2018, 21:28   #7  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Для разовой операции можно использовать дев версию этого продукта https://www.kingswaysoft.com/product...ductivity-pack
Есть возможность менять Batch size да и просто изучите их блог и мануалы, там много инсайдов найдете
Старый 03.09.2018, 22:14   #8  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Цитата:
Сообщение от Bondonello Посмотреть сообщение
Для разовой операции можно использовать дев версию этого продукта https://www.kingswaysoft.com/product...ductivity-pack
Есть возможность менять Batch size да и просто изучите их блог и мануалы, там много инсайдов найдете
Спасибо, гляну.
Старый 04.09.2018, 09:18   #9  
ZooY is offline
ZooY
Участник
Аватар для ZooY
 
379 / 46 (2) +++
Регистрация: 24.06.2008
Адрес: Россия, Москва
Для разовой операции проще использовать SSIS/ У того же KingswaySoft есть компоненты (источники, приемники) для работы с CRM https://www.kingswaysoft.com/product...t-dynamics-365. Для разовых операций компоненты бесплатны. Сам не делал но знаю что в SSIS можно распараллеливать потоки обработки, тем самым можно попытаться снизить время обработки.
__________________
Моё: Cайт - Код - Dynamics365 Tools
Старый 04.09.2018, 18:45   #10  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Поддержу высказавшихся и буду рекомендовать Kingsway Soft адаптер. На что также рекомендую обратить внимание - "Enable Multithreading" опцию - https://www.kingswaysoft.com/product...rm/destination это должно снизить время на выполнение обновления записи.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit

Последний раз редактировалось a33ik; 04.09.2018 в 23:11.
Старый 06.09.2018, 09:43   #11  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Ребята, спасибо за ссылки, несомненно попробую в следующем проекте, пока оставил как есть т.к. мапинг уже написал и логика готова. На переписать времени не дают)
Старый 06.09.2018, 14:50   #12  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Цитата:
update 1000 = ~2 минуты, итого только 83,33 часов для апдейта
Этого времени хватит с головой
Старый 06.09.2018, 17:58   #13  
Ion is offline
Ion
Участник
 
332 / 16 (1) ++
Регистрация: 19.12.2012
Его и хватило) И все получилось, просто хотелось лучше, быстрее))
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 15 Blog bot Dynamics CRM: Blogs 1 10.02.2016 10:26
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 17 Blog bot Dynamics CRM: Blogs 0 10.05.2014 06:30
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 16 Blog bot Dynamics CRM: Blogs 0 23.01.2014 03:15
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 14 Blog bot Dynamics CRM: Blogs 0 12.07.2013 07:13
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 13 Blog bot Dynamics CRM: Blogs 0 27.03.2013 22:12

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:56.