SELECT Trade.TradeId, Trade.Type, Trade.Symbol, Trade.TradeDate,
SUM(TradeLine.Notional) / 1000 AS Expr1
FROM Trade INNER JOIN
TradeLine ON Trade.TradeId = TradeLine.TradeId
WHERE (TradeLine.Id IN
(SELECT PairOffId
FROM TradeLine AS TradeLine_1
WHERE (TradeDate <= '2011-05-11')
GROUP BY PairOffId
HAVING (SUM(Notional) <> 0)))
GROUP BY Trade.TradeId, Trade.Type, Trade.Symbol, Trade.TradeDate
ORDER BY Trade.Type, Trade.TradeDate
I am concerned about the performance of the IN in the WHERE clause when the table starts to grow. Does anyone have a better strategy for this kind of query? The number of records returned by the subquery grows much slower than the number of records in the TradeLine table. The TradeLine table itself grows at a rate of 10/day.
Thank you.
EDIT: I used the idea of moving the subquery from WHERE to FROM. I voted up on all answers that contributed to this new query.
SELECT Trade.TradeId, Trade.Type, Trade.Symbol, Trade.TradeDate,
PairOff.Notional / 1000 AS Expr1
FROM Trade INNER JOIN
TradeLine ON Trade.TradeId = TradeLine.TradeId INNER JOIN
(SELECT PairOffId, SUM(Notional) AS Notional
FROM TradeLine AS TradeLine_1
WHERE (TradeDate <= '2011-05-11')
GROUP BY PairOffId
HAVING (SUM(Notional) <> 0)) AS PairOff ON TradeLine.Id = PairOff.PairOffId
ORDER BY Trade.Type, Trade.TradeDate
A subquery can be nested inside the WHERE or HAVING clause of an outer SELECT , INSERT , UPDATE , or DELETE statement, or inside another subquery.
A where clause will generally increase the performance of the database. Generally, it is more expensive to return data and filter in the application. The database can optimize the query, using indexes and partitions. The database may be running in parallel, executing the query in parallel.
A Sub-Query Does Not Hurt Performance.
The subquery in the IN
clause does not depend on anything in the outer query. You can safely move it into FROM
clause; a sane query plan builder would do it automatically.
Also, calling EXPLAIN PLAN
on any query you're going to use in production is a must. Do it and see what the DBMS thinks of the plan for this query.
I'm a fan of temp tables when a sub-query starts returning too large a result set.
So your where
clause would just be
Where TradeLine.Id In (Select PairOffId From #tempResults)
and #tempResults
would be defined as (warning: syntax is from memory, which means there may be errors)
Select PairOffId Into #tempResults
From TradeLine
Where (TradeDate <= @TradeDate)
//I prefer params in case the query becomes a StoredProc
Group By PairOffId
Having (Sum(Notional) <> 0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With