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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 04.12.2006, 12:18   #1  
Rect is offline
Rect
Участник
 
43 / 11 (1) +
Регистрация: 29.05.2006
Разница между запросами
Подскажите, кто знает, есть ли разница между запросами:

1) select A join B
where A.Field1 == param1 &&
B.Field1 == param2 &&
A.Field2 == B.Field2

2) select A where A.Field1 == param1
join B where B.Field1 == param 2 &&
B.Field2 == A.Field2

Relatoins между таблицами нету.
Старый 04.12.2006, 12:23   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Rect Посмотреть сообщение
Подскажите, кто знает, есть ли разница между запросами:
логической разницы нет - вы получите одинаковые результаты.
разница только в скорости - вы получите одинаковые результаты с разной скоростью.

скорость зависит от многих вещей:
1. прежде всего от размера таблиц
2. от индексов
3. от параметров оптимизатора
4. от параметров самой аксапты (как она помогает оптимизатору)
__________________
полезное на axForum, github, vk, coub.
Старый 04.12.2006, 14:18   #3  
Rect is offline
Rect
Участник
 
43 / 11 (1) +
Регистрация: 29.05.2006
1) Таблица А сдержит порядка 20'000'000 записей, В - 15'000
2) Для таблицы В при выполнении запроса индекс используется. Здесь всё нормально. Для таблицы А происходит full scan. Как я понимаю, существующий индекс при этом не используется в первом случае как раз из-за структуры запроса? (оба эти запроса на скорость выполнения пока протестировать не имею возможности)
3), 4) можно немного поподробнее? Какие параметры можно смотреть?
Старый 04.12.2006, 14:37   #4  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
В общем - одно время московский MBS грешил привычкой указывать условия джойна в условии where в конце запроса. Ну то есть - что нибудь типа:
select a
join b
join c
join d
where a.field1==b.field1 and c.field2=b.field2 and d.field3==a.field2

Так вот на одном из проектов (где-то в недрах книг покупок/продаж) обнаружилось что такой код, хоть и отрабатывает, но выполняется неадекватно много времени.
Как показало вскрытие, если MS SQL обрабатывает join нескольких таблиц без условия where для каждого join, то он СНАЧАЛА всегда строит картезианское произведение этих таблиц и только потом накладывает на него условия из последнего where (в котором с его точки зрения должны стоять не условия джойнов, а условия фильтрации результата).

После того как я это дело вылечил - написал в MBS и они у себя в этом конкретном месте подправили в новых сервис-паках. Возможно - в каких-то других местах кода подобные нехорошие джойны остались. Не уверен. Кроме того - это кажется на MS SQL 2000 SP3 было. Может с тех пор сам SQL Server научился более грамотно подобные запросы обрабатывать.
За это сообщение автора поблагодарили: belugin (10), Russland (1).
Старый 04.12.2006, 14:49   #5  
Rect is offline
Rect
Участник
 
43 / 11 (1) +
Регистрация: 29.05.2006
2 fed,
У нас используется Oracle. Как он реагирует на подобные вещи - не знаю, но есть подозрение что как раз возникает подобная ситуация. На днях думаю появится возможность это проверить.
Старый 04.12.2006, 15:32   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Rect Посмотреть сообщение
1) Таблица А сдержит порядка 20'000'000 записей, В - 15'000
Если такое соотношение будет и в будущем и будет примерно постоянным, то лучше
select B where B.Field1 == param 2
join A where A.Field1 == param1
B.Field2 == A.Field2

Цитата:
Сообщение от Rect Посмотреть сообщение
2) Для таблицы В при выполнении запроса индекс используется. Здесь всё нормально. Для таблицы А происходит full scan. Как я понимаю, существующий индекс при этом не используется в первом случае как раз из-за структуры запроса? (оба эти запроса на скорость выполнения пока протестировать не имею возможности)
Если вы используете параметры по-умолчанию, то скорее всего да.
Но надо смотреть.

Я не понимаю утверждения "не имею возможности протестировать скорость".
Вы задаете теоретические вопросы?
Создайте пару таблиц, заполните их и попробуйте.
Если такие таблицы есть, то почему нет возможности протестировать?

Цитата:
Сообщение от Rect Посмотреть сообщение
3), 4) можно немного поподробнее? Какие параметры можно смотреть?
Для начала в конфигурационной утилите
все что связано с literal'ами, order by clause from where
прочитайте про хинты nestedloop и т.п.
http://axapta.mazzy.ru/lib/indexhints/

Потом читайте про работу оптимизатора в BOL.
про статистику и т.п.
__________________
полезное на axForum, github, vk, coub.
Старый 04.12.2006, 18:02   #7  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от fed Посмотреть сообщение
В общем - одно время московский MBS грешил привычкой указывать условия джойна в условии where в конце запроса.
О, знакомый симптом: классы FactureCalcSettlement_RU, FactureCalcBalances_RU метод calcFactureAmounts. Простое изменение порядка условий ускорило выполнение почти в 100 раз!
За это сообщение автора поблагодарили: Denicce (1).
Старый 05.12.2006, 08:40   #8  
KiselevSA is offline
KiselevSA
Злыдни
Аватар для KiselevSA
Злыдни
Лучший по профессии 2015
 
958 / 333 (13) ++++++
Регистрация: 25.01.2002
Адрес: Москва
Есть по этому поводу хорошая книга Д.Тоу "Настройка SQL. Для професионалов", в которой рассмотрен порядок соединения исходя из веса возвращаемых данных из связанных таблиц и условий фильтрации. Наличие правильной статистики и тюнинг запроса иногда кардинально улучшают скорость выборки.
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании.
Старый 05.12.2006, 10:04   #9  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Есть мнение, что разницы между запросами из 1го поста нет, так как Аксапта сгенерит из них совершенно одинаковые SQL-предложения.
Старый 05.12.2006, 10:30   #10  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Согласен с Wamr - запросы получатся в принципе похожие.
Различие будет в порядке следования полей в предложении where и в расстановке скобок. И более того - перестановка таблиц в селекте тоже не будет иметь эффекта.

Думаю, что причина неиспользования индекса по таблице A в том, что запрос по таблице B возвращает множество записей. Причем, скорее всего, включены плейсхолдеры, в результате чего оптимизатор не может предсказать статистику для запроса по таблице B и по-этому идет по пессимистичному плану. А дальше - уже рашает, что сканирование по таблице A будет дешевле.
Как варианты:
1. Попробовать включить литералы (forceliterals) в запросе. Не уверен действенности этого совета. Все зависит от правильности статистики по таблицам и распределении значений.
2. Попробовать явно указывать индексные хинты для таблицы A. Опять-таки - все зависит от распределения значений по таблицам. В принципе - это в большой степени экспериментальный путь
3. Самый простой путь - разбить запрос на два. Внешний цикл - по таблице B. Внутри цикла - запрос по таблице A. При этом для внутреннего запроса явно указать forceplaceholders.
__________________
Axapta v.3.0 sp5 kr2
Старый 05.12.2006, 10:39   #11  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от Wamr Посмотреть сообщение
Есть мнение, что разницы между запросами из 1го поста нет, так как Аксапта сгенерит из них совершенно одинаковые SQL-предложения.
При соединении 2-х таблиц возможно Аксапта и перестроит запрос сама. А вот при большем количестве таблиц - точно нет. Причем, даже оптимизатор MS SQL (по крайней мере MS SQL 2000) не справится. Пример с методом calcFactureAmounts вполне реальный.
Старый 05.12.2006, 10:43   #12  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
2 fed
Думаю, что ваше замечание относится к запросу такого вида
X++:
select a
exists join b where a.parm1 == parm1 && a.filed1 == b.field1
Если посмотреть на запрос, отправляемый на сервет, то увидим вот что
X++:
select *
from a
where exists(select 'x' from b where a.parm1 = parm1 and a.field1 = b.field1)
(Я опустил фильтр по компании (dataAreaId). В данном случае это не существенно)
Т.е. при таком запросе условие a.parm1 == parm1 накладывается не на таблицу A, а на связь таблицы A и таблицы B. Будут выбраны все записи для таблицы A и для каждой из них будет вызван внутренний селект. С точки зрения логики запросы будет идентичны - в обоих случаях получаем идентичный набор записей
Кстати, замечание Raven Melancholic - как раз для такого типа запросов.
Это же относится и к notexists join запросам.

Для простого join'а будет генерировать такой запрос
X++:
select *
from a, b
where (a.dataareaid = 'EXT') and ((b.adataareaid = 'EXT') and ((a.parm1=parm1) and (a.field1=b.field1)))
Оптимизатор что MS SQL, что Oracle нормально обрабатывает такие запросы.
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Logger (2).
Старый 05.12.2006, 12:14   #13  
Himan is offline
Himan
Участник
Аватар для Himan
 
312 / 12 (1) ++
Регистрация: 07.11.2006
Адрес: Tumen
Lightbulb
Цитата:
Сообщение от Rect Посмотреть сообщение
Подскажите, кто знает, есть ли разница между запросами:

1) select A join B
where A.Field1 == param1 &&
B.Field1 == param2 &&
A.Field2 == B.Field2

2) select A where A.Field1 == param1
join B where B.Field1 == param 2 &&
B.Field2 == A.Field2

Relatoins между таблицами нету.
если исходита из теории БД то второе условие более правильное т.к. выборка при этом меньше, ведь не все записи из таб А обединяются с Б а только нужные, из-за чего происходит этономия времени и ресурсов
Старый 05.12.2006, 12:44   #14  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
to andyD.
Посмотрел. Действительно в последних sp генерируется правильный джойн. А вот года два с лишним назад (тогда кажется sp1 был) для такого запроса генерировалось что-то типа
select *
from a inner join b on a.dataAreaid=b.dataareaid inner join c.dataareaid=a.dataAreaId
where a.field1=b.field2 и т.п.
И от таких запросов оптимизатор регулярно уводило в картезианское произведение таблиц.
Или там даже в явном виде генерировалось ядром аксапты слово cross join...
Не помню уже если честно
Но в общем - переделка таких запросов реально на порядок ускоряло работу.
Теги
производительность, запрос (query), axapta

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Разница NotInTTS и Found Logger DAX: База знаний и проекты 6 18.09.2008 12:35
В чем разница между salesline.QtyOrdered и SalesQty? Jab Straight DAX: Функционал 5 19.06.2007 17:04
Разница между пустой Группой на форме, и группой в которую включён элемент 3oppo DAX: Программирование 8 26.12.2006 10:47
Разница между английской и русской документацией Sirius DAX: Функционал 4 22.06.2005 15:02
Расчеты между компаниями Yuri Nikitenko DAX: Функционал 9 15.11.2004 08:49

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

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

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