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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 11.01.2008, 12:25   #1  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
? LIKE VS EXISTS JOIN
Всем превед!

Представим следующую ситуацию: есть табличка LedgerTrans с большим количеством записей (порядка 500 тыс.). Соответственно нужно выбрать из нее только записи, у которых счет равен 10.100 и 10.200. Внимание - вопрос!

Какой запрос отработает быстрее?
1. select LedgerTrans exist join param where LedgerTrans.AccountNum == param.AccountNum (param - табличка, в которой перечислены нужные счета, в нашем случае 10.100 и 10.200).
2. select LedgerTrans where LedgerTrans.AccountNum like "10.*"

Последний раз редактировалось CDR; 11.01.2008 в 12:38.
Старый 11.01.2008, 12:27   #2  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
А если взять да попробовать?
Старый 11.01.2008, 12:28   #3  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
А так
X++:
select LedgerTrans where LedgerTrans.AccountNum >= "10."
&&
LedgerTrans.AccountNum <= "10.Я" // или LedgerTrans.AccountNum < "10<соедующий символ после точки>"
Старый 11.01.2008, 12:35   #4  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от kashperuk Посмотреть сообщение
А если взять да попробовать?
Уже пробую .
Интересует просто механизмы этих двух конструкций и их соответственно теоритическое быстродействие
Старый 11.01.2008, 12:35   #5  
egorych is offline
egorych
Участник
Самостоятельные клиенты AX
Oracle
 
761 / 154 (7) ++++++
Регистрация: 09.11.2006
Адрес: Краснодарский край
Если по AccountNum есть индекс, то с точки зрения SQL - like будет меньше ресурсов потреблять чем join. И потом exist join не факт что будет 1 запросом работать на сервере.
Старый 11.01.2008, 12:39   #6  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
Доп вопросы:
1. Какое число записей в LedgerTrans соответствуют условию ?
2. Какие индексы есть на таблице LedgerTrans ?
3. Таблица Param постоянная или временная ?
4. Какие индексы есть на таблице Param ?
5. Какое выравнивание у поля LedgerTrans.AccountNum, влево или вправо ?
Старый 11.01.2008, 12:40   #7  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от egorych Посмотреть сообщение
Если по AccountNum есть индекс, то с точки зрения SQL - like будет меньше ресурсов потреблять чем join. И потом exist join не факт что будет 1 запросом работать на сервере.
Больше интересует скорость исполнения, а не потребляемые ресурсы. Что выполниться быстрее: построится join или просканируется like?
Старый 11.01.2008, 12:46   #8  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
Цитата:
Сообщение от CDR Посмотреть сообщение
Больше интересует скорость исполнения, а не потребляемые ресурсы. Что выполниться быстрее: построится join или просканируется like?
В большинстве случаев, чем меньше серверу потребуется ресурсов для выполнения запроса, тем быстрее он выполнится.
Старый 11.01.2008, 12:55   #9  
tourist is offline
tourist
Участник
 
21 / 14 (1) ++
Регистрация: 03.05.2006
Цитата:
Сообщение от CDR Посмотреть сообщение
Всем превед!

Представим следующую ситуацию: есть табличка LedgerTrans с большим количеством записей (порядка 500 тыс.). Соответственно нужно выбрать из нее только записи, у которых счет равен 10.100 и 10.200. Внимание - вопрос!

Какой запрос отработает быстрее?
1. select LedgerTrans exist join param where LedgerTrans.AccountNum == param.AccountNum (param - табличка, в которой перечислены нужные счета, в нашем случае 10.100 и 10.200).
2. select LedgerTrans where LedgerTrans.AccountNum like "10.*"
Эти два запроса не эквивалентны, если нет уверенности, что все 10* счета записаны в табличку param и что так будет всегда.
Старый 11.01.2008, 12:59   #10  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от tourist Посмотреть сообщение
Эти два запроса не эквивалентны, если нет уверенности, что все 10* счета записаны в табличку param и что так будет всегда.
Вопрос был не о эквивалентности двух запросов, а немного о другом
Старый 11.01.2008, 13:00   #11  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
tourist, я полагаю теоретически вариант 2. быстрее, так как SQL в 1. варианте не знает, что можно обойтись index scan по AccountNum, и в 1 варианте сначала сделать tableScan по param, потом nestedLoop по всем записям и indexSсan по LedgerTranns
Старый 11.01.2008, 13:32   #12  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Хм... Только что опробовал обе конструкции на тестовой табличке с количеством записей около 200 тыс. Результат поразил, однако...
Конструкция с exist join выигрывает в скорости более чем в 10 раз

Ваши каменты по этому поводу?
Старый 11.01.2008, 13:40   #13  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
А планчики можно?

А мой вариант?
Старый 11.01.2008, 13:55   #14  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Честно говоря, тоже думал, что второй будет работать быстрее.
Особенно учитывая, что у LedgerTrans есть индекс, где первым полем идет AccountNum.

Планы бы действительно интересно было посмотреть.
Старый 11.01.2008, 14:15   #15  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от CDR Посмотреть сообщение
Хм... Только что опробовал обе конструкции на тестовой табличке с количеством записей около 200 тыс. Результат поразил, однако...
Конструкция с exist join выигрывает в скорости более чем в 10 раз
Ваши каменты по этому поводу?
Предварительный диагноз - некорректный тест
Например, запрос в QA без фильтра на DataAreaId
ну и опять же метания между
Цитата:
в нашем случае 10.100 и 10.200)
и
Цитата:
where LedgerTrans.AccountNum like "10.*"
, что есть немного неравнозначные условия

покажи (ничего, что я на ТЫ? ) запросы и планы
__________________
-ТСЯ или -ТЬСЯ ?
Старый 11.01.2008, 14:25   #16  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
Думаю, что Join быстрее при наличии индекса, так как с Like он не используется
Старый 11.01.2008, 14:39   #17  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
select LedgerTrans where LedgerTrans.AccountNum >= "10."
&&
LedgerTrans.AccountNum < "10/"
Старый 11.01.2008, 14:39   #18  
egorych is offline
egorych
Участник
Самостоятельные клиенты AX
Oracle
 
761 / 154 (7) ++++++
Регистрация: 09.11.2006
Адрес: Краснодарский край
!
Цитата:
Сообщение от NNB Посмотреть сообщение
Думаю, что Join быстрее при наличии индекса, так как с Like он не используется
если like '10%' то используется и очень даже эффективно!
Старый 11.01.2008, 14:44   #19  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Thumbs up
Условия и план проведенного мной теста:

1. Создаем тестовую табличку Trans из двух полей: Id и Name.
2. На табличке создаем неуникальный индекс по полю Id, который делаем кластерным.
3. Создаем джобик, который в цикле наполняет эту таблицу значениями. У меня был такой: внешний цикл i от 1 до 40 000, внутренний цикл j от 1 до 12. Во внутреннем цикле вставляются записи в табличку из пункта 1 (Id = strfmt('%1',j)). Джобик рекомендуется запускать на довольно мощном серваке, а то уснуть можно
4. Создаем табличку Params с одним полем Id, На табличке создаем уникальный индекс, который делаем Primary и кластерным. В табличку вводим значения "1", "10", "11", "12".
5. Пишем тестовый джоб. В моем случае было два select'а:

select count(recId) from Trans
exists join Params
where Trans.Id == Params.Id;

select count(recId) from Trans
where Trans.Id like '1*';

Между select'ами смотрим время (я пользовался WinAPI::getTickCount() вместо timeNow(), дает более точное значение ).

6. Джобик запускаем пару раз, что б снизить влияние всякого там кэша. Затем можно поменять select'ы местами, для большей уверености

7. Результатами делимсо тут.

У меня, как я уже писал, exists join "сделал" like более чем в 10 раз
Старый 11.01.2008, 14:47   #20  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от belugin Посмотреть сообщение
select LedgerTrans where LedgerTrans.AccountNum >= "10."
&&
LedgerTrans.AccountNum < "10/"
Я уже писал, но для особенных повторю .
Вопрос не в том, какие варианты возможны?... как это лучше реализовать?... и т.п.

Вопрос в том, что быстрее exists join или like.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Вопрос к знатокам алгоритма периодического сопоставления ATimTim DAX: Программирование 14 15.02.2007 12:36
Вопрос к знатокам Аксапты: Как завести заявку на покупку материалов? tav DAX: Функционал 19 25.07.2006 10:53
вопрос знатокам andreynikolai DAX: Программирование 7 18.11.2003 13:24
Вопрос знатокам о договоре по внедрению Pavel M DAX: Прочие вопросы 30 21.10.2003 10:11
Вопрос знатокам QBE и Query в AXAPTA Maxim Gorbunov DAX: Программирование 6 27.12.2002 13:19

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

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

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