|  30.01.2019, 20:12 | #1 | 
| Участник | Denis Trunin's Blogs: Blocking in D365FO(and why you shouldn't always follow MS recommendations) 
			
			Источник: https://denistrunin.com//understanding-sql-blocking/ ============== Understanding blocking is a key component of resolving performance issues. You can have fast CPU, a lot of memory, but if you face SQL blocking problem all these will not be fully utilized Источник: https://denistrunin.com//understanding-sql-blocking/ 
				__________________ Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. | 
|  | 
|  31.01.2019, 12:37 | #2 | 
| Moderator | 
			
			Я просто добавлю, что update_recordset (точнее говоря - update в SQL Server) вешает блокировки не только на те записи, которые он реально обновляет, но и на те записи, которые попали в выборку по индексу. Ну то есть - если у нас подходящего индекса нету, то SQL может попробовать поискать по какому-то случайному индексу по dataAreaId, а перед поиском - попробуем все это ненадолго заблокировать. Плюс - иногда SQL Server переглючивает или индексы фрагментируются или еще что-то подобное случается, и оно выбирает план исполнения по не тому индексу. В этом случае тоже случаются аналогичные блокировки. В то же время, если нам надо обновить не 100-200, а эдак 100K-200K записей, то особой альтернативы update_recordset просто нету. Да - есть вероятность блокировок. Да - надо строить правильные индексы. Да надо регулярно их перестраивать и строить статистику. Да -есть вероятность время от времени нарваться на блокировки. Но просто в каждом конкретном случае мы должны сравнивать риски больших задержек из за пошагового обновления и риски задержек из за взаимных блокировок. Плюс - я не уверен что во всех сценариях мы можем создавать отдельную транзакцию на каждое обновление. При этом если у нас одна большая транзация и обновление идет по одной записи в while select forupdate, то порядок обновления в разных кусках кода вполне может быть разным. (К слову сказать - в исходном примере вообще в while select не стоит order by, соответственно порядок обновления записей не является гарантированым...) Последний раз редактировалось fed; 31.01.2019 в 12:53. | 
|  | |
| За это сообщение автора поблагодарили: mazzy (2), trud (5), Logger (5). | |
|  31.01.2019, 13:05 | #3 | 
| Участник | Цитата: ЗЫ: Еще они не используют find, а всегда перечисляют список полей, типа так еще быстрее  , это наверное будет тема для следующего поста | 
|  | |
| За это сообщение автора поблагодарили: EVGL (15). | |
|  31.01.2019, 13:17 | #4 | 
| Участник | 
			
			Очень странно, вы нарушили две рекомендации (не делать длинных транзакций и иметь покрывающий индекс для where) чтобы показать, что тогда третья рекомендация не будет работать. А дальше сомнительные, ничем не подкрепленный вывод: Цитата: 
		
			Try to avoid any update_recordset and delete_from usage by default(especially in document posting operations). Use it only when you are 100% sure that it will not cause blocking and you really need to reduce the operation time
		
	 Что вообще такое document posting ? И если вы уже говорите ut when someone tries to update the same table using a different set of fields(for example Field2 and Field4) we'll get blocking again., то используя ваш подход можно преположить, что любой кусок кода может быть использован кем-то дргуим как-то не так и надо быть к этому готовым! Т.е. все может стать document posting, чтобы это не было.   | 
|  | 
|  31.01.2019, 13:28 | #5 | 
| Участник | |
|  | 
|  31.01.2019, 13:29 | #6 | 
| Moderator | 
			
			Я просто замечу что две первых рекомендации не всегда выполнимы. Если разносится большой документ, то на короткие транзации это не порезать. Кроме того - покрывающий индекс на каждую возможную комбинацию полей в where тоже не всегда доступен. Кроме того, как я уже написал, время от времени (особенно на квазивременных таблицах типа InventSumDeltaDim), SQL Server переглючивает и он выбирает неправильный индекс, даже если правильный покрывающий индекс присутствует.
		 | 
|  | 
|  31.01.2019, 13:35 | #7 | 
| Участник | 
			
			ну это постинг любых документов, закупок, заказов журналов - там где это наиболее критично. т.е. кейс - нам надо обновить что-то в нашей таблице, когда происходит разноска ну в общем случае select forupdate не блокируется.Исключение составляет эскаляция блокировок, но это уже другая тема Цитата: 
		
			Сообщение от skuull
			   И если вы уже говорите ut when someone tries to update the same table using a different set of fields(for example Field2 and Field4) we'll get blocking again., то используя ваш подход можно преположить, что любой кусок кода может быть использован кем-то дргуим как-то не так и надо быть к этому готовым! Т.е. все может стать document posting, чтобы это не было.   | 
|  | 
|  31.01.2019, 13:38 | #8 | 
| Участник | Цитата: 
		
			Сообщение от fed
			   Я просто замечу что две первых рекомендации не всегда выполнимы. Если разносится большой документ, то на короткие транзации это не порезать. Кроме того - покрывающий индекс на каждую возможную комбинацию полей в where тоже не всегда доступен. Кроме того, как я уже написал, время от времени (особенно на квазивременных таблицах типа InventSumDeltaDim), SQL Server переглючивает и он выбирает неправильный индекс, даже если правильный покрывающий индекс присутствует.   | 
|  | |
| За это сообщение автора поблагодарили: ax_mct (3). | |
|  31.01.2019, 13:45 | #9 | 
| Участник | 
			
			Это та же самая тема. Вопрос эскалации встает при больших количествах данных\пользователей\потоков и говорить "тут больше 1-2х строк не будет" звучит не убидительно. Сегодня нет, а завтра поменяется бизнес процесс и их будет тысячи, что сядем все переписывать?
		 | 
|  | 
|  31.01.2019, 13:56 | #10 | 
| Moderator | Цитата: А мы потом, по возможности, тоже поищем в нем ошибки и слегонца постебемся.   | 
|  | 
|  31.01.2019, 14:00 | #11 | 
| Участник | Цитата: Цитата:  Подобный вопрос обычно задавали при завершении стажировки в Коламбусе - какой вариант быстрее 1 или 2 X++: CustTable       custTable;
        ;
        //1
        select AccountNum from custTable
            where custTable.AccountNum == "C-0000101";
        custTable = null;    
        //2
        custTable = custTable::find("C-0000101"); | 
|  | 
|  31.01.2019, 21:17 | #12 | 
| Участник | Цитата:   | 
|  | 
|  01.02.2019, 00:06 | #13 | 
| Участник | |
|  | 
|  01.02.2019, 01:04 | #14 | 
| Banned | Цитата: 
		
			Сообщение от trud
			   Ага, именно это и посыл поста, используем только когда нужно Вы реально не знаете или это просто флуд?  Подобный вопрос обычно задавали при завершении стажировки в Коламбусе - какой вариант быстрее 1 или 2 X++: CustTable       custTable;
        ;
        //1
        select AccountNum from custTable
            where custTable.AccountNum == "C-0000101";
        custTable = null;    
        //2
        custTable = custTable::find("C-0000101"); | 
|  | 
|  01.02.2019, 01:06 | #15 | 
| Banned | |
|  | 
|  01.02.2019, 04:26 | #16 | 
| Участник | Цитата:   | 
|  | |
| За это сообщение автора поблагодарили: trud (1). | |
|  01.02.2019, 06:46 | #17 | 
| Участник | 
			
			Ну главная идея была дать понять, что любую вещь связанную с производительностью надо проверять. Т.е. обычно отвечали что меньше полей, значит запрос меньше. А как посмотреть посмотреть запрос - ну включить трассировку - ну давай посмотрим... смотрим - они одинаковы
		 | 
|  | 
|  01.02.2019, 07:30 | #18 | 
| Участник | 
			
			А вот тут можно подробнее, почему одинаково (пусть это уже и оффтоп)?  Вроде в случае когда у нас указан набор полей, у нас меньше количество данных передаваемых между клиентом-сервером, и поэтому работать должно быстрее? Best practicies опять же, настаивают именно на варианте "укажите в запросе конкретные нужные вам поля" | 
|  | 
|  01.02.2019, 08:22 | #19 | 
| Участник | Цитата: Цитата: А если переменную назвать не "custTable", а "с" будет быстрее? (сорри за стеб) А есть ссылка? | 
|  | 
|  01.02.2019, 08:40 | #20 | 
| Участник |   Цитата: 
		
			Сообщение от Pandasama
			   А вот тут можно подробнее, почему одинаково (пусть это уже и оффтоп)?  Вроде в случае когда у нас указан набор полей, у нас меньше количество данных передаваемых между клиентом-сервером, и поэтому работать должно быстрее? Best practicies опять же, настаивают именно на варианте "укажите в запросе конкретные нужные вам поля" Видимо вам надо в коламбус на месяцок, подтянуть основы на стажеровочке   Последний раз редактировалось skuull; 01.02.2019 в 08:42. | 
|  |