mysql - 我怎样才能加速这个(相对简单的)查询

标签 mysql

我有一个相对简单的查询,它只是将我的网站已接受的所有 PayPal 付款相加,然后使用每天更新的货币换算表将它们全部转换为英镑。

SELECT SUM(PPI.mc_gross * IF(PPI.mc_currency='GBP', 1, CC.fConv))

FROM paypal_payment_info PPI

JOIN currency_conversions CC ON CC.sFrom = PPI.mc_currency AND CC.tConv = DATE(PPI.tIPN)

对于 PPI 中的 30,000 行和 CC 中的 5,000 行,在功能强大的机器上查询大约需要 9 秒。

解释显示:

id  select_type table   type    possible_keys   key key_len ref rows Extra
1   SIMPLE  PPI ALL                 31271   
1   SIMPLE  CC  ref sFrom   sFrom   9   db.PPI.mc_currency  1167    Using where

我已尝试在 tIPN 和 mc_currency 上建立索引,以及在 mc_currency 和 tIPN 上建立索引。都没有帮助。我认为可能是 DATE() 函数出了问题,因此创建了一个列 tIPNdate 并修改了相关索引以使用它,但没有任何区别。

我觉得我遗漏了一些明显的东西,有人可以帮忙吗?

谢谢

最佳答案

对于这么多数据来说,9 秒并不是一个极端的性能问题。

话虽如此,将其分解为两个不同的 SUM() 操作可能是有意义的。

首先,查询英镑交易。

SELECT SUM(PPI.mc_gross)
  FROM paypal_payment_info PPI
 WHERE PPI.mc_currency = 'GBP'

(mc_currency, mc_gross) 上的复合索引将使该查询尽可能快。这可能会让您无需任何连接即可完成大部分交易。希望更快。

然后,处理非英镑交易。

SELECT SUM(PPI.mc_gross * CC.fConv)
  FROM paypal_payment_info PPI
  JOIN currency_conversions CC ON CC.sFrom = PPI.mc_currency 
                             AND CC.tConv = DATE(PPI.tIPN)
 WHERE PPI.mc_currency <> 'GBP'

要清除 JOIN 中不可控制的 DATE() 部分,请执行以下操作:

SELECT SUM(PPI.mc_gross * CC.fConv)
  FROM paypal_payment_info PPI
  JOIN currency_conversions CC ON PPI.mc_currency = CC.sFrom
                              AND PPI.tPN >= CC.tConv
                              AND PPI.tPN <  CC.tConv + INTERVAL 1 DAY
 WHERE PPI.mc_currency <> 'GBP'

虽然不确定,但我认为 paypal_ payment_info( tPN, mc_currency, mc_gross) 上的复合索引将有助于此查询。我认为 currency_conversions (sFrom, tConv, fConv) 上的索引也会有所帮助。

然后,您可以使用 UNION ALL 和另一个 SUM 将两个查询的结果相加。

SELECT SUM(sums) sums
  FROM (
              SELECT SUM(PPI.mc_gross) sums
                FROM paypal_payment_info PPI
               WHERE PPI.mc_currency = 'GBP'
      UNION ALL
              SELECT SUM(PPI.mc_gross * CC.fConv) sums
                FROM paypal_payment_info PPI
                JOIN currency_conversions CC ON PPI.mc_currency = CC.sFrom
                                            AND PPI.tPN >= CC.tConv
                                            AND PPI.tPN <  CC.tConv + INTERVAL 1 DAY
               WHERE PPI.mc_currency <> 'GBP'
       ) s

关于mysql - 我怎样才能加速这个(相对简单的)查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39701308/

相关文章:

php - 秒更新sql数据的最佳方式

php从文本字段到数组

php - 如何更新数据库中已插入并稍后删除的值

php - 重写时的数据库查询

mysql - 有没有办法通过将重复值替换为空来选择行

php - 一对多和一对多关系 laravel

mysql - SQL "Replace Into"删除我的一些行

Mysql - 如何根据 Blob 部分的二进制比较来选择行

python - 如何创建连接到客户 mysql 的收藏夹表

mysql - 表没有改变