Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all articles
Browse latest Browse all 7251

любители CTE узнали о табличных параметрах (to Mike_za)

$
0
0
как-то меня тут спросили, что в Reason for eEarly Termination of Statement
для наших гениальных запросов от любителей CTE,
а я говорю, переписываю нафиг, не пытаясь скомпилировать.

а сегодня думаю ок, посмотрю.
ну там Time Out, а что ждали

вот планец картинкой.

вот проца как образец применения табличного параметра через ж.
+
create procedure [dbo].[sp_MSA_Get_DataVintage]
(
	@tElencoPratiche dbo.tMSA_Pratica readonly	 
)
as
begin
 
	declare @tPratiche table
	(
		NUM_PRAT int,
		DATARICMAN date
	)
	 
	insert into @tPratiche
	select
		p.NUM_PRAT,
		p.DATARICMAN
		
	from
		coresql7.dbo.legprati p
		inner join @tElencoPratiche e on p.NUM_PRAT = e.NUM_PRAT
		
	 
	;with tUltimaDataDegradoNoTransito as
	(
		select 
			x.NUM_PRAT,
			x.data_valido_al ULTIMA_DATA_DEGRADO 
			
		from
		(
			select
				ROW_NUMBER() over (partition by lps.NUM_PRAT order by lps.data_valido_al desc) RowNumber,
				lps.NUM_PRAT,
				lps.data_valido_al 
			
			from
				(
					select 
						a.NUM_PRAT, 
						a.IDBanca, 
						a.cod_portafoglio, 
						a.CODRESPINT, 
						a.data_valido_al 
						
					from 
						coresql7.dbo.legprati_storico a
						inner join  @tElencoPratiche b on a.NUM_PRAT = b.NUM_PRAT
						
					union 
					
					select 
						a.NUM_PRAT, 
						a.IDBanca, 
						a.cod_portafoglio, 
						a.CODRESPINT ,
						'99990101' 
					
					from 
						coresql7.dbo.legprati a
						inner join  @tElencoPratiche b on a.NUM_PRAT = b.NUM_PRAT
				) lps 

				inner join coresql7.dbo.Collegamenti_contratto_portafoglio ccp on lps.cod_portafoglio = ccp.cod_portafoglio and lps.IDBanca = ccp.idbanca
				inner join coresql7.dbo.legutent lu on lu.CODUTENTE = lps.CODRESPINT
				inner join  coresql7.dbo.profili pf on pf.codprofilo = lu.CODPROFILO
			
			where
				ccp.tipo_contratto in (2, 3, 7)
				and lps.cod_portafoglio  not in (9, 3636, 3637, 3638, 3639, 3640)
				and  pf.codufficio not in (16, 17, 20)
		    
		) x
		
		where
			x.RowNumber = 1 
	 
	)
	--  prima data di degrado per le pratiche degradate
	, tPrimaDataDegradoNoTransito as
	(

		select
			NUM_PRAT,
			data_valido_al PRIMA_DATA_DEGRADO
		
		from
		(
			select 
				ROW_NUMBER() over (partition by y.NUM_PRAT order by lps.data_valido_al desc) RowNumber,
				y.NUM_PRAT,
				lps.data_valido_al  
				
			from
			(
				select	
					*
					
				from
				(
			
					select
						ROW_NUMBER() over (partition by lps.NUM_PRAT order by lps.data_valido_al asc) RowNumber,
						p.NUM_PRAT,
						lps.data_valido_al 
					
					from
						@tPratiche p
						inner join  coresql7.dbo.legprati_storico lps on p.NUM_PRAT = lps.NUM_PRAT
						inner join coresql7.dbo.Collegamenti_contratto_portafoglio ccp on lps.cod_portafoglio = ccp.cod_portafoglio and lps.IDBanca = ccp.idbanca
						inner join coresql7.dbo.legutent lu on lu.CODUTENTE = lps.CODRESPINT
						inner join  coresql7.dbo.profili pf on pf.codprofilo = lu.CODPROFILO
					
					where					
						ccp.tipo_contratto in (2, 3, 7)
						and lps.cod_portafoglio  not in (9, 3636, 3637, 3638, 3639, 3640)
						and  pf.codufficio not in (16, 17, 20)

				) x
				
				where
					x.RowNumber = 1 
				
			) y
			inner join  coresql7.dbo.legprati_storico lps on y.NUM_PRAT = lps.NUM_PRAT
		 
		 where
			lps.data_valido_al < y.data_valido_al
		
		) k
		where 
			k.RowNumber = 1 
	)

	-- data di passaggio a degrado
	, tDataPassaggioDegrado as
	(
		select 
			x.NUM_PRAT,
			x.DATA_PASSAGGIO_DEGRADO
				
		from
		(
			select
				ROW_NUMBER() over (partition by lps.NUM_PRAT order by lps.data_valido_al desc) RowNumber,
				lps.NUM_PRAT,
				case 
					/*se ad oggi non sono degradate ... */
					when ccp2.tipo_contratto not in (2,3,7) then null
					else
					
						/* se hanno degrado e non una prima data degrado allora prendo il prim valore della
						   legprati_storico */
						   isnull(tP.PRIMA_DATA_DEGRADO, lps.data_valido_al) 
						   
				end DATA_PASSAGGIO_DEGRADO
				
			from
				tUltimaDataDegradoNoTransito d 
				left join coresql7.dbo.legprati_storico lps	on d.NUM_PRAT = lps.NUM_PRAT
				left join coresql7.dbo.Collegamenti_contratto_portafoglio ccp on lps.cod_portafoglio = ccp.cod_portafoglio and lps.IDBanca = ccp.idbanca
				left join tPrimaDataDegradoNoTransito tP on d.NUM_PRAT = tP.NUM_PRAT
				left join coresql7.dbo.legprati p on lps.NUM_PRAT = p.NUM_PRAT
				left join coresql7.dbo.Collegamenti_contratto_portafoglio ccp2 on p.cod_portafoglio = ccp2.cod_portafoglio and p.IDBanca = ccp2.idbanca
			
			where
				 cast(lps.data_valido_al as date) < d.ULTIMA_DATA_DEGRADO
				 and ccp.tipo_contratto not in (2, 3, 7)
		    
		) x
		
		where
			x.RowNumber = 1 
	)
	--/*ultima data di transito */
	, tDataUscitaTransito as
	(	
		select 
			NUM_PRAT,
			case 
				when data_valido_al	= '99990101' then null 
				else data_valido_al
			end ULTIMA_DATA_USCITA_TRANSITO
		from
		(
			select
				ROW_NUMBER() over (partition by lps.NUM_PRAT order by lps.data_valido_al desc) RowNumber,
				lps.*

			from
				@tPratiche p
				inner join 
				(
					select 
						a.NUM_PRAT, 
						a.cod_portafoglio, 
						a.CODRESPINT, 
						a.data_valido_al 
					
					from 
						coresql7.dbo.legprati_storico  a
						inner join  @tElencoPratiche b on a.NUM_PRAT = b.NUM_PRAT
						
					union
					 
					select 
						a.NUM_PRAT, 
						a.cod_portafoglio, 
						a.CODRESPINT ,
						'99990101' 
						
					from 
						coresql7.dbo.legprati a
						inner join  @tElencoPratiche b on a.NUM_PRAT = b.NUM_PRAT
				) lps 
				on p.NUM_PRAT = lps.NUM_PRAT
				inner join coresql7.dbo.legutent lu on lu.CODUTENTE = lps.CODRESPINT
				inner join coresql7.dbo.profili pf on pf.codprofilo = lu.CODPROFILO 
				
			where
				(lps.cod_portafoglio  in (9, 3636, 3637, 3638, 3639, 3640)
				or pf.codufficio in (16,17,20))

		) lps

		where
			lps.RowNumber = 1
	)  
	 
	select
		t.NUM_PRAT,
		cast(t.DATA_VINTAGE as date) DATA_VINTAGE

	from
	(
		select
			p.NUM_PRAT,
			case 
				when (d.DATA_PASSAGGIO_DEGRADO is null and t.ULTIMA_DATA_USCITA_TRANSITO is null) then 
						 p.DATARICMAN
						 
					when d.DATA_PASSAGGIO_DEGRADO is not null and t.ULTIMA_DATA_USCITA_TRANSITO is null then  
						case when d.DATA_PASSAGGIO_DEGRADO > p.DATARICMAN then d.DATA_PASSAGGIO_DEGRADO else p.DATARICMAN end
						
					when d.DATA_PASSAGGIO_DEGRADO is not null and t.ULTIMA_DATA_USCITA_TRANSITO is not null then 
						case when d.DATA_PASSAGGIO_DEGRADO > t.ULTIMA_DATA_USCITA_TRANSITO  then d.DATA_PASSAGGIO_DEGRADO else t.ULTIMA_DATA_USCITA_TRANSITO end
				  
					when d.DATA_PASSAGGIO_DEGRADO is null and t.ULTIMA_DATA_USCITA_TRANSITO is not null then 
						t.ULTIMA_DATA_USCITA_TRANSITO
				
			end DATA_VINTAGE 

		from
			@tPratiche  p
			left join tDataUscitaTransito t on p.NUM_PRAT = t.NUM_PRAT
			left join tDataPassaggioDegrado d on p.NUM_PRAT = d.NUM_PRAT

	) t


end


они передают угадайте, что.
да есть уже таблица постоянная, каждый день заполняемая.
вот ее копируют в переменную,
а переменную передают в процедуру

какая красота!
сегодня пришлось это все килить после 2ух часов работы.
на входе таблица в 2,5 млн, ей же самое место в переменной,
инкапсуляция же.
сервер считает, что на выходе 1 строка,
и хотя во всех соединениях hash join,
как только выплывает переменная, так сразу Nested Loops.
и уходит в кому
----
думаете, мне сказало спасибо чучелко за переписывание его процедуры,
к-ая теперь 30 секунд работает только превращением CTE в #CTE
и обращением напрямую к таблице в 2,5 млн строк?
не, оно теперь обиженно со мной не разговаривает вообще
----
to Колосов: вот какой тут нафиг OLAP?
это же бубль гум какой-то, вот они, наши мины и максы, считаемые через row_number() = 1, ибо модно.
----
логика их мне неведома, но в результате беспредел на сервере.
если кто желает план, могу подарить.
разумеется, оценочный
----
извиняюсь за выплеск, жаловаться больше некому, просто не поймут

Viewing all articles
Browse latest Browse all 7251

Trending Articles