SQL Server:存储过程中的查询优化

时间:2019-01-02 05:26:30

标签: sql sql-server-2016

请让我知道如何优化此SQL Server查询:

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

2 个答案:

答案 0 :(得分:1)

您可以使用first_value的分析函数从CurrencyRates表中获取所有数据并将其连接一次,而不是在select查询中进行选择。

如果您要批量处理数据(即您希望针对要返回的所有行优化选择输出),这将很有用

如果您要构建带有分页功能的app / ui屏幕,则在select中进行选择会更合适,因为它会优化为首先获得first_rows。

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

答案 1 :(得分:1)

您好Shailesh Kalasariya,

您可以外部申请将这些顶级子查询组合成一个子查询,就像这样。

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

或者您可以使用row_number函数重写它。

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

最好的问候,