2010-09-28 103 views
0

该查询在我的慢查询日志弹出:什么指数(ES)需要添加此查询正常工作?

SELECT 
    COUNT(*)     AS ordersCount, 
    SUM(ItemsPrice + COALESCE(extrasPrice, 0.0)) AS totalValue, 
    SUM(ItemsPrice)   AS totalValue, 
    SUM(std_delivery_charge) AS totalStdDeliveryCharge, 
    SUM(extra_delivery_charge) AS totalExtraDeliveryCharge, 
    this_.type    AS y5_, 
    this_.transmissionMethod AS y6_, 
    this_.extra_delivery  AS y7_ 
FROM orders this_ 
WHERE this_.deliveryDate BETWEEN '2010-01-01 00:00:00' AND '2010-09-01 00:00:00' 
    AND this_.status IN(1, 3, 2, 10, 4, 5, 11) 
    AND this_.senderShop_id = 10017 
GROUP BY this_.type, this_.transmissionMethod, this_.extra_delivery 
ORDER BY this_.deliveryDate DESC; 

表是InnoDB和拥有大约880K行和9-12秒之间需要执行。我尝试添加下列指数ALTER TABLE orders ADD INDEX _deliverydate_senderShopId_status (deliveryDate , senderShop_id , status, type, transmissionMethod, extra_delivery);,但没有实际收益。任何帮助和/或建议是欢迎

这里是查询执行计划现在:

 
id  select_type table type possible_keys key     key_len ref rows filtered Extra 
1  SIMPLE  this_ ref      FKC3DF62E57562BA6F 8   const 139894 100.00 Using where; Using temporary; Using filesort 

我拿出possible_keys值出来的文字,因为我认为它在表中列出的所有索引。 (FKC3DF62E57562BA6F)所使用的关键看起来像

 
Keyname    Type Unique Packed Field   Cardinality Collation Null Comment 
FKC3DF62E57562BA6F BTREE No  No  senderShop_id 4671  A 
+0

deliveryDate的列类型是什么? – Thilo 2010-09-28 08:20:57

+0

索引应与查询计划分析结合使用,以查看它们如何被真正使用。关于数据库如何基于数据库完成的优化使用索引并不总是很明显。发布您的查询计划与此索引,然后我们将在一个更好的位置来帮助 – InSane 2010-09-28 08:23:49

+0

@Thilo - deliveryDate是datetime – 2010-09-28 08:33:27

回答

1

我要告诉你一件事,你可以看看以提高速度。

您一般只在对未知或不适用的行中的数据NULL值。在我看来,因为无论如何您都将NULL视为0,您应该考虑摆脱它们并确保所有extrasPrice值为0,因为它们之前为NULL,以便您可以摆脱时间处罚​​3210。

事实上,你可以走一步,并介绍另一列称为totalPrice您有插入/更新触发器与实际值ItemsPrice + extrasPrice或(ItemsPrice + COALESCE(extrasPrice,0.0)如果你还需要的extrasPrice为空)设置。

然后,您可以简单地使用:

SELECT 
    COUNT(*)   AS ordersCount, 
    SUM(totalPrice) AS totalValue, 
    SUM(ItemsPrice) AS totalValue2, 
    : 

(我不知道,你应该有两个输出列具有相同的名称,或者是否是一个错字,这将是,在最坏的情况中,错误,充其量,混淆)。

这将移动计算的成本,插入/更新时间,而不是选择时间,在摊销所有的选择是成本 - 大多数数据库表中读取的次数远远多于写的。数据的一致性由于触发器而保持不变,并且性能应该更好,但需要考虑一些存储要求。

但是,因为绝大多数的数据库的问题是“我怎样才能获得更快的速度?”而不是“如何使用更少的磁盘?”,这通常是一个好主意。

另一个建议是提供关于降低你的结果集最快(高基数)的列中的非复合索引。换句话说,如果您在表格中仅存储了两周的数据(14个不同的日期),但是有400个不同的商店,则您应该有一个senderShop_id索引,并确保您的统计数据是最新的。

这应该引起DBMS执行引擎,以削减使用该密钥,以便后续操作更快的结果集。

deliveryDate,senderShop_id,...的复合指数将无法使用senderShop_id来削减的结果,因为关键的排序将是senderShop_iddeliveryDate