| 
			
			 | 
		#1 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
			
			 
			
			Всем превед! 
		
		
		
		
		
		
		
		
			Представим следующую ситуацию: есть табличка 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.  | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А если взять да попробовать?  
		
		
		
		
		
		
			
		
		
		
		
	 
		 | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А так 
		
		
		
		
		
		
		
	X++: select LedgerTrans where LedgerTrans.AccountNum >= "10." && LedgerTrans.AccountNum <= "10.Я" // или LedgerTrans.AccountNum < "10<соедующий символ после точки>"  | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 MCTS 
		
			
	 | 
	
	|
| 
	
 | 
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Если по AccountNum есть индекс, то с точки зрения SQL - like будет меньше ресурсов потреблять чем join. И потом exist join не факт что будет 1 запросом работать на сервере.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Доп вопросы: 
		
		
		
		
		
		
		
	1. Какое число записей в LedgerTrans соответствуют условию ? 2. Какие индексы есть на таблице LedgerTrans ? 3. Таблица Param постоянная или временная ? 4. Какие индексы есть на таблице Param ? 5. Какое выравнивание у поля LedgerTrans.AccountNum, влево или вправо ?  | 
| 
	
 | 
| 
			
			 | 
		#7 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
 
		 | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	|
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Сообщение от 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 | 
| 
			
			 MCTS 
		
			
	 | 
	
	|
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			tourist, я полагаю теоретически вариант 2. быстрее, так как SQL  в 1. варианте не знает, что можно обойтись index scan по AccountNum, и в 1 варианте сначала сделать tableScan по param,  потом nestedLoop по всем записям и indexSсan по LedgerTranns
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#12 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Хм... Только что опробовал обе конструкции на тестовой табличке с количеством записей около 200 тыс. Результат поразил, однако...  
		
		
		
		
		
		
		
	Конструкция с exist join выигрывает в скорости более чем в 10 раз ![]() Ваши каменты по этому поводу?  
		 | 
| 
	
 | 
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А планчики можно? 
		
		
		
		
		
		
		
	А мой вариант?  | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Честно говоря, тоже думал, что второй будет работать быстрее.  
		
		
		
		
		
		
			
		
		
		
		
	Особенно учитывая, что у LedgerTrans есть индекс, где первым полем идет AccountNum. Планы бы действительно интересно было посмотреть.  | 
| 
	
 | 
| 
			
			 | 
		#15 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Например, запрос в QA без фильтра на DataAreaId ну и опять же метания между Цитата: 
	
		
			в нашем случае 10.100 и 10.200)
		
	 
Цитата: 
	
		
			where LedgerTrans.AccountNum like "10.*"
		
	 
покажи (ничего, что я на ТЫ?   ) запросы и планы
		
				__________________ 
		
		
		
		
	-ТСЯ или -ТЬСЯ ?  | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Думаю, что Join быстрее при наличии индекса, так как с Like он не используется
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#17 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			select LedgerTrans where LedgerTrans.AccountNum >= "10." 
		
		
		
		
		
		
		
	&& LedgerTrans.AccountNum < "10/"  | 
| 
	
 | 
| 
			
			 | 
		#18 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			 | 
| 
	
 | 
| 
			
			 | 
		#19 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
			
			 
			
			Условия и план проведенного мной теста: 
		
		
		
		
		
		
		
	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 раз  
		 | 
| 
	
 | 
| 
			
			 | 
		#20 | 
| 
			
			 MCTS 
		
			
	 | 
	
	|
| 
	
 |