Question

I am trying to insert top 253 values for each trader from a temp traders table into temp results table.

I am using following code to do it.

CREATE TABLE #trad ( Trad varchar(50))    
IF @trad is not null    
INSERT INTO #Trad    
SELECT DISTINCT * FROM dbo.Split(@trad,',') -- split will have traders seperated by commas          
ELSE INSERT INTO #Traders    
Select distinct Trader from TraderMap tm     
where traderorgroup = 'trader'  


CREATE TABLE #result      
(port VARCHAR(50),portdate DATE,P MONEY,V_95 MONEY,      
V_99 MONEY,VLimit MONEY,V_90 MONEY,H_99 MONEY,      
H_975 MONEY,H_95 MONEY,H_90 MONEY,H_80 MONEY,dCnt 
INT,Trad varchar(100))  

DECLARE @traderlist AS Varchar(100)      
DECLARE traderlist CURSOR FOR      
SELECT DISTINCT Traders FROM #traders      
OPEN traderlist      
FETCH next FROM traderlist INTO @traderlist      
WHILE @@FETCH_STATUS = 0      
BEGIN  
INSERT INTO #result (port, portdate, P, V_95, V_99, VLimit, 
dCnt,Trad)      
SELECT  TOP 253 pl.Port,pl.Portdate,pl.dtd_P 
PL,var.V_95,var.V_99, sum(gu.Guid * -1) VLimit,      
Row_number() OVER(partition by pl.TradName ORDER BY Portdate DESC) 
dCnt,pl.TradName      
FROM Trad_PL pl INNER JOIN rep_tab var      
ON pl.Portdate = var.V_Date      
AND pl.Port = var.Port     
AND pl.TradName = var.Trad      
INNER JOIN Trad_Guid gui      
ON pl.Port = gui.Port     
AND pl.TradName = gui.Trad      
WHERE pl.Portdate <= @portdate      
AND pl.Port = CASE WHEN @port = 'Her' THEN 'Herport' ELSE 
@port END      
AND pl.ONA = 'Act'  
AND pl.TradName = @tradlist          
AND var.PType = '0Trad' 
group by  
pl.TradName,pl.Port,pl.Portdate,pl.dtd_P,var.V_95,var.V_99
ORDER BY Portdate DESC
FETCH next FROM tradlist INTO @tradlist      
END      
CLOSE tradlist      
DEALLOCATE tradlist    

This code runs for hours. Is there any efficient way to get top 253 rows for each trad from Trad_PL and rep_tab.

Was it helpful?

Solution

In general if you have a cursor that's your first place to look for performance issues. It probably works great if you have 10 traders, not so well if you have 10,000.

Try this.

INSERT INTO #result (port, portdate, P, V_95, V_99, VLimit, dCnt,Trad)      
SELECT pl.Port,pl.Portdate,pl.dtd_P 
    PL,var.V_95,var.V_99, sum(gu.Guid * -1) VLimit,      
    Row_number() OVER(partition by pl.TradName ORDER BY Portdate DESC) 
    dCnt,pl.TradName      
FROM Trad_PL pl 
INNER JOIN #Traders
    ON #Traders.Traders = pl.TradName
INNER JOIN rep_tab var      
    ON pl.Portdate = var.V_Date      
    AND pl.Port = var.Port     
    AND pl.TradName = var.Trad      
INNER JOIN Trad_Guid gui      
    ON pl.Port = gui.Port     
    AND pl.TradName = gui.Trad      
WHERE pl.Portdate <= @portdate      
    AND pl.Port = CASE WHEN @port = 'Her' THEN 'Herport' ELSE @port END      
    AND pl.ONA = 'Act'  
    AND var.PType = '0Trad' 
    AND dCnt <= 253
group by  
    pl.TradName,pl.Port,pl.Portdate,pl.dtd_P,var.V_95,var.V_99
ORDER BY Portdate DESC

I removed the where clause that hit @tradlist and just joined to your temp table (which was already created from a distinct list of traders so no worries there). I also eliminated the TOP 253. You are already creating a row number with your dCnt field so I just added an entry to the WHERE clause where dCnt <= 253.

If you are still having performance problems I'd make sure you have indexes related to each of your joins and take a look at the query plan. Performance tuning in general is a big subject but you could do worse than buying a copy of Grant Fritchey's Execution Plan book. There is even a free ebook copy.

https://www.red-gate.com/simple-talk/books/sql-server-execution-plans-third-edition-by-grant-fritchey/

Last but not least, completely away from your actual question, formatting is your friend when posting pieces of code. You are far more likely to get positive responses (and answers) if your code is easier to read. If you look, the piece of code I am posting is formatted to make it easier to read. You certainly don't have to use this particular layout, formatting can be a very personal thing, but something other than all of the code down the left hand side of the screen is usually helpful.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top