使用SUM()缓慢的MySQL查询

时间:2018-01-04 17:41:36

标签: mysql query-performance

我必须在我的代码中运行两个查询才能让我的租户保持平衡。但是,这些查询太慢了。

首先查询,我得到所有租户及其单位名称:

SELECT t.TenantID 
  FROM Tenants t
  JOIN Units u
    ON t.UnitID = u.UnitID
 Where t.Prospect = 2 
   AND t.PropertyID = 8
 ORDER 
    BY CONCAT(Left(Replace(UnitName,'-',''),2),
              REPEAT('0', (10-CHAR_LENGTH(UnitName))),
              Right(Replace(UnitName,'-',''),
                    CHAR_LENGTH(Replace(UnitName,'-',''))-2
             )     )

它返回500行

然后我在4个条件下获得余额。此查询将在第一个查询循环内:

Select
        SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) AS TotalDebit,
        SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) AS HousingDebit,
        SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) AS TotalCredit,
        SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) AS HousingCredit
    From TenantTransactions
    Where TenantID= FirstQuery.TenantID

我的查询错了吗?它需要1分钟才能运行。

2 个答案:

答案 0 :(得分:2)

使用GROUP BY在单个查询中执行此操作。

尝试这样的事情:

SELECT t.TenantID, TotalDebit, HousingDebit, TotalCredit, HousingCredit
  FROM Tenants t
  JOIN Units u ON t.UnitID = u.UnitID
  LEFT JOIN (
        Select
          TenantID,
          SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) AS TotalDebit,
          SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) AS HousingDebit,
          SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) AS TotalCredit,
          SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) AS HousingCredit
        From TenantTransactions
       Group By TenantID
       ) sums ON sums.TenantID = t.TenantID
 Where t.Prospect = 2 
   AND t.PropertyID = 8
 ORDER 
    BY CONCAT(Left(Replace(UnitName,'-',''),2),REPEAT('0', (10-CHAR_LENGTH(UnitName))),Right(Replace(UnitName,'-',''),CHAR_LENGTH(Replace(UnitName,'-',''))-2))

内部查询可能仍会运行一段时间,但只能运行一次。

尝试在TenantTransactions上包含这些列的复合覆盖索引:(TenantID, TransactionTypeID, ChargeTypeID, TransactionAmount)以使用其中的SUM优化查询。

Tenants上尝试使用列(PropertyID, Prospect)的复合索引。

答案 1 :(得分:1)

这是使用子查询执行此操作的另一种方法。您知道,性能问题可能不是数据库性能,而是数据库和应用程序服务器之间的来回。这就是单个查询有用的地方。

SELECT t.TenantID,
  (SELECT SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) From TenantTransactions TT WHERE TT.TenantID=t.TenantID) AS TotalDebit,
  (SELECT SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) From TenantTransactions TT WHERE TT.TenantID=t.TenantID) AS HousingDebit,
  (SELECT SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID != 6 THEN TransactionAmount ELSE 0 END) From TenantTransactions TT WHERE TT.TenantID=t.TenantID) AS TotalCredit,
  (SELECT SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID = 6 THEN TransactionAmount ELSE 0 END) From TenantTransactions TT WHERE TT.TenantID=t.TenantID) AS HousingCredit  
  FROM Tenants t
  JOIN Units u
    ON t.UnitID = u.UnitID
 Where t.Prospect = 2 
   AND t.PropertyID = 8
 ORDER 
    BY CONCAT(Left(Replace(UnitName,'-',''),2),REPEAT('0', (10-CHAR_LENGTH(UnitName))),Right(Replace(UnitName,'-',''),CHAR_LENGTH(Replace(UnitName,'-',''))-2))