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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.02.2013, 15:00   #1  
Xardas is offline
Xardas
Участник
 
28 / 13 (1) ++
Регистрация: 19.09.2012
Цитата:
Сообщение от kair84 Посмотреть сообщение
Важно помнить что макроподстановка выполняется в момент компиляции, а не в момент исполнения !
Вот это и настораживает.
Получается, что макросы в принципе нединамические. Как бы макрос не был написан, в конкретном месте основной программы все равно будет либо exists, либо notexists.

Цитата:
Сообщение от twilight Посмотреть сообщение
Еще как вариант можно join из запросов вообще убрать. А есть ли запись в связанной таблице проверять отдельно.
Это вообще не вариант. Представляете, как упадет производительность данного кода?

Похоже, придется использовать вариант
X++:
if (flag)
  select...
else
  select...
Что же, спасибо всем за уделенное время.
Старый 13.02.2013, 15:26   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от twilight Посмотреть сообщение
Еще как вариант можно join из запросов вообще убрать. А есть ли запись в связанной таблице проверять отдельно.
Цитата:
Сообщение от Xardas Посмотреть сообщение
Это вообще не вариант. Представляете, как упадет производительность данного кода?
Далеко не факт. Это надо проверять экспериментально. Как раз тот случай, когда "теоретические" рассуждения не могут дать однозначный ответ. Надо проверять.

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

Кстати, ведь по описанному Вами условию, Вы имеет "зеркальные" выборки. Это значит, что если Exists будет выполняться быстро, то not Exists неизбежно будет выполняться медленно. Или наоборот. И далеко не факт, что перенесение проверки внутрь цикла существенно повлияет на среднее время выполнения. Повторюсь, это проверить надо.

А "в общем случае" рассуждения на подобную тему мало полезны. Именно в силу того, что неизвестны детали задачи. Вполне возможно, что задачу можно решить и без использования Exists просто модифицировав запрос. Однако без знания конкретной постановки задачи заранее сказать нельзя можно это сделать или нет.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 13.02.2013, 15:58   #3  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,342 / 3563 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Кстати, ведь по описанному Вами условию, Вы имеет "зеркальные" выборки. Это значит, что если Exists будет выполняться быстро, то not Exists неизбежно будет выполняться медленно. Или наоборот.
Необязательно. Например, на форму подтягиваются только отображаемые записи в грид (плюс-минус еще несколько). И будет там exists или notexists - это уже не столь важно.

Проверял на АХ 2009, когда делал грид из InventTable с 70 тыс записями. Я добавлял туда к каждой записи галку "Маркировать" (edit-метод) и добавлял в контекстное меню по правой кнопке мыши пункт "Фильтр по выделенному" по этому edit-методу. Маркироваться могли абсолютно непредсказуемые записи и в больших количествах (>1000). Соответственно - для целей фильтрации в коде в одном случае - делался exists join, в другом - not exists. Работало одинаково.

А вот то, что разбивать не стоит - факт.
Опять-таки - пример. Запустите расчет сводного плана, имея большой справочник номенклатур. Если у Вас заполнены Настройки-Покрытие номенклатуры (ReqItemTable) - то расчет отработает. Если не заполнены - то не отработает. Обратите внимание - сколько времени отрабатывает "вхолостую" расчет, просто бегая в цикле по большому справочнику номенклатуры. Хотя простейшая оптимизация вида InventTable exists join ReqItemTable могла бы делать пересчет сводного плана мгновенным, при условии, что записей в ReqItemTable много меньше, чем в InventTable
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 13.02.2013 в 16:02.
Старый 13.02.2013, 16:15   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
А вот то, что разбивать не стоит - факт.
Нет. Не факт Я же говорю, когда речь идет об exist, то все надо проверять экспериментально. Практический результат (скорость выполнения) - слабо предсказуем "теоретическими" рассуждениями.

Тут "фишка" в том, что физически на MS SQL сервере выполняется не "голый" запрос, а запрос "обернутый" в курсор (DECLARE CURSOR ... FOR). Как следствие, планы выполнения "голого" запроса и курсора могут существенно отличаться. Однако здесь ключевое слово "могут". Могут отличаться, а могут и не отличаться. Зависит от кучи условий, не всеми из которых можно управлять.

Лично я "напоролся" на подобные различия именно в запросах с Exists. В запросах, где exists отсутствует я подобных различий не наблюдал. Отсюда и повышенная настороженность к подобным запросам.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 13.02.2013, 20:46   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5813 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Xardas Посмотреть сообщение
Имеется класс с большим количеством запросов вида
X++:
select tbl1
exists join tbl2
where tbl2.field1 == tbl1.field1
Сейчас возникла необходимость модифицировать данный код: Если значение некоторой логической переменной истина, то соединение таблиц должно производиться с помощью exists join. Если значение этой же логической переменной ложь, то соединение должно производиться с помощью notexists join. Можно ли произвести данную модификацию?
Есть время разбрасывать камни и время их собирать. Кто-то поленился нормально написать код, избавиться от дублирования, вынести принятие однотипных решений в одно место, а теперь придется либо наплодить кучу copy-paste'а, либо засучить рукава и провести серьезный рефакторинг кода.
Цитата:
Сообщение от Xardas Посмотреть сообщение
Похоже, придется использовать вариант
X++:
if (flag)
  select...
else
  select...
Что же, спасибо всем за уделенное время.
Не стоит так делать. Тут уже писали, наиболее нормальный вариант, позволяющий менять тип join'а во время выполнения, - это переписать код на Query'ках. Решать проблему copy-paste'ом - все равно, что заметать сор под половик в надежде, что убирать его придется кому-то другому; это непрофессионально, в конце концов
За это сообщение автора поблагодарили: S.Kuskov (1).
Старый 14.02.2013, 07:40   #6  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
650 / 352 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Есть время разбрасывать камни и время их собирать. Кто-то поленился нормально написать код, избавиться от дублирования, вынести принятие однотипных решений в одно место, а теперь придется либо наплодить кучу copy-paste'а, либо засучить рукава и провести серьезный рефакторинг кода.
Не стоит так делать. Тут уже писали, наиболее нормальный вариант, позволяющий менять тип join'а во время выполнения, - это переписать код на Query'ках. Решать проблему copy-paste'ом - все равно, что заметать сор под половик в надежде, что убирать его придется кому-то другому; это непрофессионально, в конце концов
Так и я о том же. Думаю, просто как могли, так и написали. Кент Бек, Роберт Мартин, Стив Макконнелл, Мартин Фаулер просто отдыхают.
Предлагаю автора поделиться кодом.
__________________
// no comments
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AX 2012 Наследование таблиц. Краткое описание механизма sukhanchik DAX: Программирование 32 21.09.2018 17:56
Таблица, расширенный тип данных, базовый перечислимый тип или класс, вызванные test_Sdelka, уже существуют. Импортирование Table прервано. Poleax DAX: Программирование 4 17.05.2011 17:57
Тип производственного заказа Anais DAX: Функционал 17 26.05.2005 13:50
Никак не могу вьехать, для чего нужны тип счета и тип разноски maloy DAX: Функционал 5 28.03.2004 17:18
Тип связи Андре DAX: Программирование 9 25.04.2002 20:20
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

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

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

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