Please let me know how can optimize this SQL Server query:
SELECT
C.Id AS CurrencyId, C.DisplayName AS CurrencyName,
C.TickerSymbol AS TickerSymbol,
m.DisplayName AS MarketName, C.BaseCurrency AS BaseCurrency,
C.BaseCurrencySymbol AS CurrencySymbol, C.IsActiveImport AS ActiveImport,
(SELECT TOP 1 Price
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS Price,
(SELECT TOP 1 Open_24h
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS Open24H,
(SELECT TOP 1 Volume_24h
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS Volume24H,
(SELECT TOP 1 Low_24h
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS Low24H,
(SELECT TOP 1 High_24h
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS High24H,
(SELECT TOP 1 BestBid
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS BestBid,
(SELECT TOP 1 BestAsk
FROM CurrencyRates
WHERE C.Id = ProductId
ORDER BY PriceDate DESC) AS BestAsk
FROM
Currencies C
INNER JOIN
CryptoMarketsMaster M ON C.CryptoMarketId = C.CryptoMarketId
You can make use of analytical functions for first_value to get all of the data from CurrencyRates table and join it once instead of a select in a select query.
This would be useful if you are batch processing the data(ie you wish to optimize the select output for all the rows to be returned)
If you are building a app/ui screen with pagination then select in a select would be more suitable as it would be optimized for getting the first_rows first.
SELECT C.Id AS CurrencyId
, C.DisplayName AS CurrencyName
, C.TickerSymbol AS TickerSymbol
, m.DisplayName AS MarketName
, C.BaseCurrency AS BaseCurrency
, C.BaseCurrencySymbol AS CurrencySymbol
, C.IsActiveImport AS ActiveImport
/*
, (SELECT TOP 1 Price FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Price
, (SELECT TOP 1 Open_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Open24H
, (SELECT TOP 1 Volume_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Volume24H
, (SELECT TOP 1 Low_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Low24H
, (SELECT TOP 1 High_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS High24H
, (SELECT TOP 1 BestBid FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestBid
, (SELECT TOP 1 BestAsk FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestAsk
*/
, Cr.Price
, Cr.Open24H
, Cr.Volume24H
, Cr.Low24H
, Cr.High24H
, Cr.BestBid
, Cr.BestAsk
FROM Currencies C
INNER JOIN CryptoMarketsMaster M
ON C.CryptoMarketId = C.CryptoMarketId
JOIN (SELECT /*first_value(Price) over(partition by productId order by price_date desc) as price
,first_value(Open_24h) over(partition by productId order by price_date desc) as Open_24h
,first_value(Volume_24h) over(partition by productId order by price_date desc) as Volume_24h
,first_value(Low_24h) over(partition by productId order by price_date desc) as Low_24h
,first_value(High_24h) over(partition by productId order by price_date desc) as High_24h
,first_value(BestBid) over(partition by productId order by price_date desc) as BestBid
,first_value(BestAsk) over(partition by productId order by price_date desc) as BestAsk
*/
, Price
, Open24H
, Volume24H
, Low24H
, High24H
, BestBid
, BestAsk
,row_number() over(partition by productId order by price_date desc) as rnk
,productId
FROM CurrencyRates
)Cr
ON C.Id=Cr.productId
AND Cr.rnk=1
Hi Shailesh Kalasariya,
You could outer apply to combine these top subqueries into one subquery like this.
SELECT
C.Id AS CurrencyId,
C.DisplayName AS CurrencyName,
C.TickerSymbol AS TickerSymbol,
m.DisplayName AS MarketName,
C.BaseCurrency AS BaseCurrency,
C.BaseCurrencySymbol AS CurrencySymbol,
C.IsActiveImport AS ActiveImport,
/*
(SELECT TOP 1 Price FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Price,
(SELECT TOP 1 Open_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Open24H,
(SELECT TOP 1 Volume_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Volume24H,
(SELECT TOP 1 Low_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Low24H,
(SELECT TOP 1 High_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS High24H,
(SELECT TOP 1 BestBid FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestBid,
(SELECT TOP 1 BestAsk FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestAsk
*/
D.Price,
D.Open_24h,
D.Volume_24h,
D.Low_24h,
D.High_24h,
D.BestBid,
D.BestAsk
FROM Currencies C
INNER JOIN CryptoMarketsMaster M ON C.CryptoMarketId = C.CryptoMarketId
OUTER APPLY (SELECT TOP 1 Price,Open_24h,Volume_24h,Low_24h,High_24h,BestBid,BestAsk FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) D
Or you could use row_number function to rewrite this.
SELECT
C.Id AS CurrencyId,
C.DisplayName AS CurrencyName,
C.TickerSymbol AS TickerSymbol,
m.DisplayName AS MarketName,
C.BaseCurrency AS BaseCurrency,
C.BaseCurrencySymbol AS CurrencySymbol,
C.IsActiveImport AS ActiveImport,
/*
(SELECT TOP 1 Price FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Price,
(SELECT TOP 1 Open_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Open24H,
(SELECT TOP 1 Volume_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Volume24H,
(SELECT TOP 1 Low_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS Low24H,
(SELECT TOP 1 High_24h FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS High24H,
(SELECT TOP 1 BestBid FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestBid,
(SELECT TOP 1 BestAsk FROM CurrencyRates WHERE C.Id=ProductId ORDER BY PriceDate DESC) AS BestAsk
*/
D.Price,
D.Open_24h,
D.Volume_24h,
D.Low_24h,
D.High_24h,
D.BestBid,
D.BestAsk
FROM Currencies C
INNER JOIN CryptoMarketsMaster M ON C.CryptoMarketId = C.CryptoMarketId
LEFT JOIN (SELECT ROW_NUMBER() over (partition by ProductId ORDER BY PriceDate DESC) as RN,Price,Open_24h,Volume_24h,Low_24h,High_24h,BestBid,BestAsk,ProductId FROM CurrencyRates ) D ON D.RN=1 AND D.ProductId=C.Id
Best Regards,
Will
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.