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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.12.2016, 13:07   #1  
Pokersky09 is offline
Pokersky09
Участник
 
43 / 60 (3) ++++
Регистрация: 15.11.2012
Адрес: Turkey
! Запросы из AX на уровне SQL как Cross Join
Коллеги, добрый день!

2012R3, SQL 2014

Кто сталкивался с проблемой Cross Join

Пишется обычный запрос на Ах:

X++:
select RecId from Header

join RecID from line
where line.headerRecid == Header.RecId
&&     line.someField    == 12345
Почему такой запрос отрабатывает на уровне SQL в виде :
X++:
select RecId from Header

CROSS JOIN RecID from line
where line.headerRecid == Header.RecId
&&     line.someField    == 12345
Хотелось бы получить запрос в виде:
X++:
select RecId from Header

Inner join RecID from line
ON line.headerRecid == Header.RecId
&&     line.someField    == 12345
Пробовал переписывать этот же запрос на Query, разницы никакой нет, на sql такой же запрос.

Есть ли что-то, что позволяло бы однозначно уводить запрос в Inner Join?
Какие параметры влияют на то, что запрос строится с помощью Cross Join?

Если нужно конкретно, могу вытащить сюда конкретные запросы,
таблицы кастомные, но думаю такая же история будет и в системных
Старый 08.12.2016, 13:24   #2  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,731 / 406 (17) +++++++
Регистрация: 23.03.2006
а в чем проблема?
Старый 08.12.2016, 13:31   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Pokersky09 Посмотреть сообщение
Пишется обычный запрос на Ах:

X++:
select RecId from Header

join RecID from line
where line.headerRecid == Header.RecId
&&     line.someField    == 12345
в Аксапте нигде хинта forceNestedLoop не стоит?
Старый 08.12.2016, 14:00   #4  
Pokersky09 is offline
Pokersky09
Участник
 
43 / 60 (3) ++++
Регистрация: 15.11.2012
Адрес: Turkey
Цитата:
Сообщение от ice Посмотреть сообщение
а в чем проблема?
Cross Join по факту умножает кол-во записей между собой.
+ Where отрабатывает только в после объединения Cross.

В случае Inner Join
ON сначала ограничивает выборку, затем объединяет только по нужным.

В желаемом варианте исключена избыточная перекрестная выборка,
а также исключена излишняя выборка из-за переноса условий в блок ON.

Цитата:
Сообщение от mazzy Посмотреть сообщение
в Аксапте нигде хинта forceNestedLoop не стоит?
Нет, точно не используется


У меня подозрение в сторону каких-то параметров таблиц. Возможно в Relation свойства надо другие ставить, может ли это влиять или точно нет?
Старый 08.12.2016, 14:24   #5  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от Pokersky09 Посмотреть сообщение
Cross Join по факту умножает кол-во записей между собой.
+ Where отрабатывает только в после объединения Cross.

В случае Inner Join
ON сначала ограничивает выборку, затем объединяет только по нужным.
Это неправильное мнение)

Все зависит от того, как распределены данные (статистика), какие именно созданы индексы и еще кучи других условий

Вот вам два разных запроса, с абсолютно одинаковыми планами

X++:
select top 100 *
from INVENTJOURNALTABLE ij
inner join INVENTJOURNALTRANS ijt
on ij.DATAAREAID = ijt.DATAAREAID and ij.JOURNALID = ijt.JOURNALID
where ij.JOURNALTYPE = 0


X++:
select top 100 *
from INVENTJOURNALTABLE ij
cross join INVENTJOURNALTRANS ijt
where ij.DATAAREAID = ijt.DATAAREAID and ij.JOURNALID = ijt.JOURNALID 
and  ij.JOURNALTYPE = 0


По поводу хинта forceNestedLoop.
Он, в принципе, наоборот заставит использовать inner join, но с обязательным хинтом inner loop join. Т.е. будет принудительно устанавливаться алгоритм объединения
Миниатюры
Нажмите на изображение для увеличения
Название: InnerJoin.png
Просмотров: 1095
Размер:	18.9 Кб
ID:	11082   Нажмите на изображение для увеличения
Название: CrossJoin.png
Просмотров: 942
Размер:	18.2 Кб
ID:	11083  

__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: mazzy (2).
Старый 08.12.2016, 15:33   #6  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от Pokersky09 Посмотреть сообщение
Cross Join по факту умножает кол-во записей между собой.
+ Where отрабатывает только в после объединения Cross.

В случае Inner Join
ON сначала ограничивает выборку, затем объединяет только по нужным.
За чтож вы так не любите команду которая занимается разработкой движка оптимизатора SQL Server
Старый 09.12.2016, 12:27   #7  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
If you run the following X++ code and look at the Transact-SQL trace, you will see CROSS JOIN in the Transact-SQL statement. You might think that it misses the join condition and is doing a Cartesian product of the two tables. The join condition is actually in the where clause. A cross join like this is equivalent to an inner join with the join condition.

Источник
Старый 09.12.2016, 13:04   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Morpheus Посмотреть сообщение
The join condition is actually in the where clause. A cross join like this is equivalent to an inner join with the join condition.
Не совсем.
Эквивалентны функционально.
Но не эквивалентны с точки зрения производительности.

А вот дальше в книге приводится причина - outer join.

Pokersky09, в вашем запросе outer join есть?
Изображения
 
Старый 09.12.2016, 13:35   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Честно говоря, не понимаю общего "возбуждения"

Не знаю, как в Ax2012, но в младших версиях Axapta никогда не посылала на SQL запросы с объединением по Inner Join. Всегда на SQL отправлялись запросы вида

X++:
select Header.RecId, line.RecId

from Header, line

where     line.headerRecid == Header.RecId
      AND line.someField   == 12345
CROSS JOIN - это просто другой синтаксис того же самого. Исключение в синтаксисе делалось для Outer Join и Exists Join

Так что, можете считать это фичей Axapta. Ну, вот таким образом она конструирует синтаксис запроса. Ничего с этим не поделаешь В общем случае, на производительность это не влияет, кроме очень особых ситуаций
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 09.12.2016, 22:10   #10  
Pokersky09 is offline
Pokersky09
Участник
 
43 / 60 (3) ++++
Регистрация: 15.11.2012
Адрес: Turkey
Цитата:
Сообщение от mazzy Посмотреть сообщение
Не совсем.
в вашем запросе outer join есть?
Нет, чисто Inner Join.


Цитата:
Сообщение от mazzy Посмотреть сообщение
Эквивалентны функционально.
Но не эквивалентны с точки зрения производительности.
Именно в этом направлении и двигаюсь.

По производительности отличие существенное, когда в таблице Line 200KK+ записей, а в Header порядка 120К+(этот случай в бд разбираю).

На уровне SQL выполняя запросы на CROSS/INNER скорость существенно отличается, на кросе около 800ms самый хороший результат.

Пробовал на sql, тестил только планы запросов, без замеров времени:
Inner / Inner loop join, отличались циклом от варианта без loop,

Cost запроса CROS/INNER/LOOP_INNER = 44/44/13

Т.е. по стоимости по плану loop_Inner наиболее быстрый.

Планы CROS/INNER одинаковые, как и цена.

Позже выложу скрины по факту с временем, планами запросов и показателями таблиц

P.s. тему поднял не для теоретического рассуждения, а для реального решения проблемы

Последний раз редактировалось Pokersky09; 09.12.2016 в 22:12. Причина: отличались циклом от варианта без loop*
За это сообщение автора поблагодарили: mazzy (2).
Старый 09.12.2016, 22:21   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
По поводу хинта forceNestedLoop.
Он, в принципе, наоборот заставит использовать inner join, но с обязательным хинтом inner loop join. Т.е. будет принудительно устанавливаться алгоритм объединения
Цитата:
Сообщение от Pokersky09 Посмотреть сообщение
Нет, чисто Inner Join.
...
P.s. тему поднял не для теоретического рассуждения, а для реального решения проблемы
Попробуйте в аксапте добавить хинт forceNestedLoop сразу после select (или в свойствах query).
Получится как AndyD говорит?
Старый 13.12.2016, 01:40   #12  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Цитата:
Сообщение от mazzy Посмотреть сообщение
Но не эквивалентны с точки зрения производительности
Да эквивалентны они. AndyD выше уже показал, что план выполнения запроса будет совершенно одинаковый.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Теги
cross join, inner join, sql 2014

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
axsa: MDM Adapter - Extending Dynamics AX 2012 R3 Master Data Management Blog bot DAX Blogs 0 22.05.2014 03:28
atinkerersnotebook: Walkthrough & Tutorial Summary Blog bot DAX Blogs 1 09.09.2013 09:11
emeadaxsupport: AX 2012 reports fail to deploy on a server hosting multiple SQL Server Reporting Server instances Blog bot DAX Blogs 0 15.06.2012 11:11
gatesasbait: Dynamics AX 2009 SSRS and SSAS Integration Tips Blog bot DAX Blogs 3 09.07.2009 13:07
Dynamics AX: SQL Server, Heart of Dynamics AX Blog bot DAX Blogs 0 13.07.2007 18:00
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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