使用 SUM() 的慢 MySQL 查询

Slow MySQL queries using SUM()

我必须在我的代码中 运行 两个查询来获取我的租户余额。但是,这些查询太慢了。

第一次查询,我得到了所有租户及其单位名称:

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
             )     )

它returns 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 分钟

使用 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) 的复合索引。

这是使用子查询的另一种方法。要知道,性能问题可能不是数据库性能,而是你的数据库和应用服务器之间的来回。所以这就是单个查询会有所帮助的地方。

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))