Sql 如何加快子查询的速度,即从具有2000万行的表中选择数据
这是我的问题。此查询将导致20-30秒,并且在我的应用程序中导致超时错误。我试图用子句重写,但无法运行 对不起,我的英语很差Sql 如何加快子查询的速度,即从具有2000万行的表中选择数据,sql,sql-server,performance,tsql,subquery,Sql,Sql Server,Performance,Tsql,Subquery,这是我的问题。此查询将导致20-30秒,并且在我的应用程序中导致超时错误。我试图用子句重写,但无法运行 对不起,我的英语很差 SELECT StationName, StationID, (SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter FROM Transactions (nolock) WHERE (StationID = s.StationID) AND (SaleDate&g
SELECT
StationName, StationID,
(SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter
FROM Transactions (nolock)
WHERE (StationID = s.StationID)
AND (SaleDate>= CONVERT(date, GETDATE()))
AND (FuelTypeID = 1)) AS Total1,
(SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_11
WHERE (StationID = s.StationID)
AND (SaleDate >= CONVERT(date, GETDATE()))
AND (FuelTypeID = 2)) AS Total2,
(SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_10
WHERE (StationID = s.StationID)
AND (SaleDate >= CONVERT(date, GETDATE()))
AND (FuelTypeID = 3)) AS Total3,
(SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_9
WHERE (StationID = s.StationID)
AND (SaleDate >= CONVERT(date, GETDATE()))
AND (FuelTypeID = 4)) AS Total4,
(SELECT TOP (1) ISNULL(SUM(Liter), 0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_8
WHERE (StationID = s.StationID)
AND (SaleDate >= CONVERT(date, GETDATE()))
AND (FuelTypeID = 5)) AS Total5,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_7
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE())) AND (FuelTypeID = 6)) AS Total6,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_6
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE())) AND (FuelTypeID = 7)) AS Total7,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_5
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE())) AND (FuelTypeID = 8)) AS Total8,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_4
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE())) AND (FuelTypeID = 9)) AS Total9,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_3
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE())) AND (FuelTypeID = 10)) AS Total10,
(SELECT TOP (1) ISNULL(SUM(Liter),0) AS TotalLiter
FROM dbo.Transactions (nolock) AS Transactions_2
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE()))) AS GrandTotal,
(SELECT TOP (1) MAX(SaleDate) AS LastSaleDate
FROM dbo.Transactions (nolock) AS Transactions_1
WHERE (StationID = s.StationID) AND (SaleDate >= CONVERT(date, GETDATE()))
ORDER BY LastSaleDate) AS LastSaleDate
FROM
dbo.Stations (nolock) AS s
WHERE
s.StationCode BETWEEN 1000 AND 1100
ORDER BY
StationID
您可以使用
外部应用
和条件聚合
避免多次运行相同的子查询
试试这样的
SELECT StationName,
StationID,
Total1,
Total2,
Total3,
Total4
...
GrandTotal,
LastSaleDate
FROM dbo.Stations (nolock) AS s
OUTER apply (SELECT Sum(CASE WHEN t.FuelTypeID = 1 THEN Liter END) AS Total1,
Sum(CASE WHEN t.FuelTypeID = 2 THEN Liter END) AS Total2,
Sum(CASE WHEN t.FuelTypeID = 3 THEN Liter END) AS Total3,
Sum(CASE WHEN t.FuelTypeID = 4 THEN Liter END) AS Total4,
...
Sum(Liter) as GrandTotal,
Max(SaleDate) AS LastSaleDate
FROM Transactions t
WHERE t.StationID = s.StationID
AND t.SaleDate >= CONVERT(DATE, Getdate())) ou
WHERE s.StationCode BETWEEN 1000 AND 1100
ORDER BY StationID
也不要忘记阅读本文:您可以使用
外部应用
和条件聚合
避免多次运行相同的子查询
试试这样的
SELECT StationName,
StationID,
Total1,
Total2,
Total3,
Total4
...
GrandTotal,
LastSaleDate
FROM dbo.Stations (nolock) AS s
OUTER apply (SELECT Sum(CASE WHEN t.FuelTypeID = 1 THEN Liter END) AS Total1,
Sum(CASE WHEN t.FuelTypeID = 2 THEN Liter END) AS Total2,
Sum(CASE WHEN t.FuelTypeID = 3 THEN Liter END) AS Total3,
Sum(CASE WHEN t.FuelTypeID = 4 THEN Liter END) AS Total4,
...
Sum(Liter) as GrandTotal,
Max(SaleDate) AS LastSaleDate
FROM Transactions t
WHERE t.StationID = s.StationID
AND t.SaleDate >= CONVERT(DATE, Getdate())) ou
WHERE s.StationCode BETWEEN 1000 AND 1100
ORDER BY StationID
另外,不要忘记阅读本文:添加表结构、示例数据和预期结果D表结构、示例数据和预期结果我知道nolock的不良影响,但我把它作为最后的手段。谢谢你的回复。你的方式比我的查询要好得多,也干净得多:)我知道nolock的不良影响,但我把它作为最后的手段。谢谢你的回复。您的方式比我的查询更好、更干净:)