| 
			
			 | 
		#1 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			
			Почему join запрос разбивается на подзапросы!?
			 
			
			Axapta 3.0 SP 3 
		
		
		
		
		
		
			Имеем запрос: Код:     while select _rassetTable
        index RAssetNumIdx
        where _rassetTable.VGP_PropertyTax          == NoYes::Yes
    join firstonly _rassetTrans
        index TransTypeIdx
        where _rassetTrans.AccountNum               == _rassetTable.AccountNum          &&
              _rassetTrans.AssetTransType           == RAssetTransType::Acquisition     &&
              _rassetTrans.TransDate                <= reportDateEnd
    join firstonly _ledgerTrans
        index VGP_LedgerLinkIdx
        where _ledgerTrans.VGP_LedgerLinkId         == _rassetTrans.VGP_LedgerLinkId    &&
              _ledgerTrans.VGP_LedgerLinkModuleRef  == VGP_LedgerLinkModuleRef::RAsset  &&
              _ledgerTrans.Voucher                  == _rassetTrans.Voucher             &&
              _ledgerTrans.TransDate                == _rassetTrans.TransDate
{
	…….
	//Не значительный код, заполняется мап
}Кол-во Select 4837 !!!!!?!?!? Почему?! Запрос отрабатывает порядка 25 минут Написал такой же запрос в SQL Enterprise Manager отработал за 5 секунд!! Прямой запрос, вставлять в код не очень хочется … .. . Подскажите в чём дело и что можно сделать?! 
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Хм. А пробовали убрать firstonly? 
		
		
		
		
		
		
			
		
		
		
		
	Вполне возможно, что для каждой записи rAssetTable делается поиск записи соответствия свой вместо простого объединения таблиц. (как будто бы join вообще не было, а в теле while Вы отдельно искали требуемые записи) Хотя, это всего лишь предположение - возможно кто-то поправит.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Интересно, а какой, по вашему, запрос должен сформироваться?
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#4 | 
| 
			
			 Member 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Уровень кэширования на таблице RAssetTable у вас стандартный? Это не экземпляр временной таблицы? Запросы всегда разбиваются, если в них включена таблица с уровнем кэширования EntireTable или временная таблица.
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	С уважением, glibs®  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: zemlyn (1), kashperuk (5), Мариночка (2), 3oppo (1). | |
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Да пробовал убирать firstonly без результатно!  
		
		
		
		
		
		
			  X++: while select RPayJournalTable where RPayJournalTable.JournalId == 'ЗП000628' join RPayJournalTrans where RPayJournalTrans.JournalId == RPayJournalTable.JournalId join RPayTrans where RPayTrans.SourceRecId == RPayJournalTrans.RecId { i++; } box::info( int2str(i) ); to AndyD ну уж никак не из 4000 селектов! RAssetTable стандартно не каких временных таблиц! 
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Насколько я понял firstonly  в join-ах вообще игнорируются. У меня тоже как то получалось что join разбивал select но я так и не разобрался в чём там дело. Просто используй «прямой запрос» к базе, сам так делал. Выигрыш в скорости в РАЗЫ!!
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#7 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А вы. Не пробовали использовать стандартные Query?! Он вроде как быстрее должен работать!
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Member 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Попробовал написать джоб похожий (на стандартной функциональности только). Select один при декларировании курсора. Дольше идут вызовы управления курсором. 
		
		
		
		
		
		
			Либо вы чего-то не договариваете... А какой вид у вас имеют все 4837 запроса? Они абсолютно одинаковы? Может у вас сам метод столько раз вызывается? Тогда не удивлюсь насчет 25 мин. 
				__________________ 
		
		
		
		
	С уважением, glibs®  | 
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Прямой запрос в разы сложнее отлаживать и в разы дороже в сопровождении. Прежде чем следовать совету МРАКОбеса триджы подумайте.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#10 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Вот метод полностью: X++: protected Map initRasset01Map() { Map _ret = new Map(Types::String, Types::Date); Set _account01Set = this.initAccount01Set(); RAssetTable _rassetTable; RAssetTrans _rassetTrans; LedgerTrans _ledgerTrans; int i, ip4, ip2, ip3; while select _rassetTable index RAssetNumIdx where _rassetTable.VGP_PropertyTax == NoYes::Yes join firstonly _rassetTrans index TransTypeIdx where _rassetTrans.AccountNum == _rassetTable.AccountNum && _rassetTrans.AssetTransType == RAssetTransType::Acquisition && _rassetTrans.TransDate <= reportDateEnd join firstonly _ledgerTrans index VGP_LedgerLinkIdx where _ledgerTrans.VGP_LedgerLinkId == _rassetTrans.VGP_LedgerLinkId && _ledgerTrans.VGP_LedgerLinkModuleRef == VGP_LedgerLinkModuleRef::RAsset && //ОС _ledgerTrans.Voucher == _rassetTrans.Voucher && _ledgerTrans.TransDate == _rassetTrans.TransDate { i++; if (_account01Set.in(_ledgerTrans.AccountNum)) { _ret.insert(_rassetTable.AccountNum, this.getDisposalDate(_rassetTable.AccountNum)); } } // box::info( int2str(i) ); return _ret; } Переписал на прямой запрос в той же функции, выполняется вместо 26 минут - 30 секунд. Посмотрел генерируемые запросы, вроде одинаковые вот такого вида: SELECT A.TRANSDATE,A.RECID,A.VGP_LEDGERLINKID FROM RASSETTRANS A(INDEX(I_16077RASSETDATEIDX)) WHERE ((DATAAREAID=?) AND (((ACCOUNTNUM=?) AND (TRANSDATE<?)) AND ((((ASSETTRANSTYPE=?) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)))) OPTION(FAST 2) внутри проскакивают 2-3 другого вида но непонятно к чему они относятся. Цитата: 
	
     
		
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Не совсем понял о чём речь? 
		
		
		
		
		
		
			Согласен! А что делать?! Если разница в скорости в 50 раз!!! 
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#12 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Нисколько не сомневаюсь, что не поняли. 
		
		
		
		
		
		
			
		
		
		
		
	Но тем не менее категорично советуете. ![]() для начала назову пару вещей: виртуальные компани, rls. про autorelation, временные таблицы, вычисляемые поля, про енумы, про целостность, про переопределенные методы при чтении/вставке/записи/удалении и т.п. уж как-нибудь сами. в общем, rtfm. Во-первых, грамотно использовать втроенные средства. Во-вторых, прекратите мерить разницу в монопольном режиме. Хоть раз померяйте при нормальной загрузке sql-сервера с нормальным числом пользователей. Замерьте наконец задержки, которые происходят у других пользователей из-за ваших прямых запросов. Барабашки нет.  
		 | 
| 
	
 | 
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Сообщение от 3oppo
			 
 
			Вот метод полностью: 
		
	... Посмотрел генерируемые запросы, вроде одинаковые вот такого вида: SELECT A.TRANSDATE,A.RECID,A.VGP_LEDGERLINKID FROM RASSETTRANS A(INDEX(I_16077RASSETDATEIDX)) WHERE ((DATAAREAID=?) AND (((ACCOUNTNUM=?) AND (TRANSDATE<?)) AND ((((ASSETTRANSTYPE=?) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)))) OPTION(FAST 2) внутри проскакивают 2-3 другого вида но непонятно к чему они относятся. Здесь идет связка по OR для нескольких условий для ASSETTRANSTYPE, а в коде x++ - по одному. Попробуйте оставить только выборку и цикл по ней и посмотрите на результат запроса. 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Как только вижу в коде прямое обращние к базе, это с 99% вероятностью означает, что барабашка скоро появится. С Уважением, Георгий  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#15 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			  ?????  
		
		
		
		
		
		
			  Цитата: 
	
Научите плиз!? Вдруг чего не знаю. Цитата: 
	
Цитата: 
	
Судя по оставшемуся главному вопросу, он всё таки есть!  
		
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Пробовал коментарить код внутри цикла, на времени выполнения это не отразилось.
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| 
			
			 | 
		#17 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Еще можно включить трассировку SQL и походить по шагам внимательно глядя в список infolog дебаггера. И посмотреть какая строка генерирует приведенный SQL. 
		
		
		
		
		
		
		
	Еще можно трассировать SQL в файл и посмотреть по стеку какая строчка его генерит.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: 3oppo (1). | |
| 
			
			 | 
		#18 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
		
		 
			
			не проверял с клиентом SP3, но все же  
		
		
		
		
		
		
			- какой глубокий смысл заложен в X++: join firstonly RAssetTrans X++: join firstonly LedgerTrans - с какой целью используются X++: index RAssetNumIdx index TransTypeIdx index VGP_LedgerLinkIdx 
				__________________ 
		
		
		
		
	-ТСЯ или -ТЬСЯ ?  | 
| 
	
 | 
| 
			
			 | 
		#19 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Код достался от внедренцев ... .. . Вот пытаюсь разобраться. 
		
		
		
		
		
		
			Цитата: 
	
Вот реальный запрос PHP код: 
	
			
	
				__________________ 
		
		
		
		
		
			PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда. Последний раз редактировалось 3oppo; 25.06.2007 в 11:29.  | 
| 
	
 | 
| 
			
			 | 
		#20 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Остался вопрос ПОЧЕМУ ТАК ДОЛГО?! И почему такая большая разница с прямым запросом.
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	PS. Сложно приехать в Москву, но ещё сложнее уехать отсюда.  | 
| 
	
 | 
| Теги | 
| производительность, запрос (query), ax3.0 | 
| 
	
	 | 
	
		
		
  |