是mysql的dayofweek昂贵的记忆......或者我不应该在乎?

时间:2011-08-15 09:18:24

标签: mysql

我正在尝试使用超过3Mil的数据加速数据库选择以进行报告。使用dayofweek好吗?

查询是这样的:

SELECT 
  COUNT(tblOrderDetail.Qty) AS `BoxCount`, 
  `tblBoxProducts`.`ProductId` AS `BoxProducts`, 
  `tblOrder`.`OrderDate`,
  `tblFranchise`.`FranchiseId` AS `Franchise` 
FROM `tblOrder`
INNER JOIN `tblOrderDetail` ON tblOrderDetail.OrderId=tblOrder.OrderId
INNER JOIN `tblFranchise` ON tblFranchise.FranchiseeId=tblOrderDetail.FranchiseeId
INNER JOIN `tblBoxProducts` ON tblOrderDetail.ProductId=tblBoxProducts.ProductId
WHERE (tblOrderDetail.Delivered = 1) AND 
(tblOrder.OrderDate >= '2004-05-17') AND 
(tblOrder.OrderDate < '2004-05-24')
GROUP BY `tblBoxProducts`.`ProductId`,`tblFranchise`.`FranchiseId` 
ORDER BY `tblOrder`.`OrderDate` DESC

但我真正想要的是在一周内每天显示报告。就像星期一,星期一......

那么在查询中使用dayofweek或从视图中呈现结果会是个好主意吗?

1 个答案:

答案 0 :(得分:1)

不,使用dayofweek作为您选择的列之一不会显着损害您的性能,也不会破坏您的服务器内存。您的查询显示您正在显示七个不同的order_date天数&#39;值得的订单。也许有很多订单,但不是很多天。

但您可能最好使用DATE_FORMAT(请参阅http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format)将一周中的某一天显示为order_date列的一部分。然后你不必在你的客户转身(0..6)进入(星期一......周日)或是(星期日......星期六)?你明白我的观点。

一个好的选择是将现有查询包装在一个额外的查询中,仅用于格式化。这不会花费太多,并且可以让您控制演示文稿,而不会使您的数据检索查询更复杂。

另请注意,您从GROUP BY表达式中省略了order_date。我认为这会在mySql中产生不可预测的结果。在Oracle中,它会产生错误消息。另外,我不知道你对这个结果集做了什么,但是你不想通过特许经营和盒装产品以及日期订购吗?

我假设您的OrderDate列仅包含天数 - 也就是说,这些列值中的所有时间都是午夜。如果OrderDate列中存在实际的订单时间戳,您的GROUP BY将无法执行您希望的操作。如果您不确定,请使用DATE()函数确保这一点。请注意,对于带有时间戳的日期,您在WHERE子句中执行日期范围的方式已经正确。 http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date

所以,这是您查询的建议修订版。我没有修复排序,但我修复了GROUP BY表达式并使用了DATE()函数。

SELECT BoxCount, BoxProducts, 
       DATE_FORMAT(OrderDate, '%W') AS DayOfWeek,
       OrderDate,
       Franchise
FROM (
  SELECT 
    COUNT(tblOrderDetail.Qty) AS `BoxCount`, 
    `tblBoxProducts`.`ProductId` AS `BoxProducts`, 
    DATE(`tblOrder`.`OrderDate`) AS OrderDate,
    `tblFranchise`.`FranchiseId` AS `Franchise` 
  FROM `tblOrder`
  INNER JOIN `tblOrderDetail` ON tblOrderDetail.OrderId=tblOrder.OrderId
  INNER JOIN `tblFranchise` ON tblFranchise.FranchiseeId=tblOrderDetail.FranchiseeId
  INNER JOIN `tblBoxProducts` ON tblOrderDetail.ProductId=tblBoxProducts.ProductId
  WHERE (tblOrderDetail.Delivered = 1) 
    AND (tblOrder.OrderDate >= '2004-05-17')
    AND (tblOrder.OrderDate < '2004-05-24')
  GROUP BY `tblBoxProducts`.`ProductId`,`tblFranchise`.`FranchiseId`, DATE(`tblOrder`.`OrderDate`) 
  ORDER BY DATE(`tblOrder`.`OrderDate`) DESC
) Q

你有很多内部联接操作;此查询可能还需要一段时间。确保tblOrder在OrderDate上有某种索引以获得最佳性能。