0

有没有办法优化以下查询。大约需要 11 秒:

SELECT 
    concat(UNIX_TIMESTAMP(date), '000') as datetime, 
    TRUNCATE(SUM(royalty_price*conversion_to_usd*
             (CASE WHEN sales_or_return = 'R' THEN -1 ELSE 1 END)*
             (CASE WHEN royalty_currency = 'JPY' THEN .80 
                   WHEN royalty_currency in ('AUD', 'NZD') THEN .95 ELSE 1 END) )
    ,2) as total_in_usd
FROM 
    sales_raw 
GROUP BY
    date 
ORDER BY
    date ASC

做一个解释我得到:

1   SIMPLE  sales_raw   index   NULL    date    5   NULL    735855  NULL
4

3 回答 3

2

这是评论中问题的答案。它在这里的格式更好:

过滤一组索引日期的示例意味着执行以下操作:

where date >= AStartDateVariable
and date < TheDayAfterAnEndDateVariable

如果日期字段上没有索引,则创建一个。

于 2013-04-03T19:54:09.997 回答
2

您也许可以加快速度。您似乎对date. 发生的事情是在索引中读取行,然后查找每一行。如果数据不是按日期字段排序的,那么这可能不是最佳的,因为读取将在本质上是随机页面。在原始表不适合内存的情况下这会导致称为“页面抖动”的情况。需要一条记录,从内存中读取该页面(在内存缓存中替换另一个页面),并且下一次读取也可能导致缓存未命中。

要查看是否发生这种情况,我会建议两件事之一。(1) 尝试删除索引date或将group by条件切换为concat(UNIX_TIMESTAMP(date), '000')。其中任何一个都应该删除索引作为一个因素。

从您的附加评论来看,这并没有发生,尽管索引的好处似乎很小。

(2) 您还可以扩展索引以包含查询中使用的所有表。除日期外,该指数还需要包含版税_价格、转换为美元、销售或退货和版税_货币。这将允许索引完全满足查询,而无需在页面中查找其他信息。

您还可以与您的 DBA 确认您有足够大的页面缓存来匹配您的硬件功能。

于 2013-04-03T19:55:44.357 回答
0

这是一个简单的 group by 查询,甚至不涉及连接。我希望问题出在您正在使用的功能上。

请从一个简单的查询开始,仅检索日期和 conversion_to_usd 的总和。检查性能并逐步建立查询,始终检查性能。很快就能发现罪魁祸首。

Concats 通常是缓慢的操作,但我想知道 sum 之后的 truncate 是否会使优化器感到困惑。第二种情况可以通过使用带有货币代码表和相应百分比的连接来代替,但它并不明显会产生很大的不同。首先找出罪魁祸首。

您还可以存储具有正确数量的值,但这会引入非规范化。

于 2013-04-03T21:02:13.657 回答