订单BY DESC的查询优化

时间:2017-12-16 16:44:54

标签: mysql sql-order-by

表格中的记录总数"采取" = 12 000。

我在下面的查询中只需要10条记录,这些记录是最近或最后添加的记录。因此我应用OrderBy desc,但是当我在出价时使用ORDER BY应用DESC时它将挂起并且查询将在15分钟内返回输出10个记录。

 SELECT taking.BId ,taking.calledDate Called,taking.calleduser Caller,taking.callerNotes,taking.Title,
taking.FName,taking.ScName,taking.takingPhase, Training.TName,
taking.TrDate,taking.SubmitDateTime, TrLocation.TrLocation trTrl,
taking.STATUS,taking.DelegNum, taking.Tel, taking.Email,taking.Notes
FROM Taking taking
LEFT JOIN training Training ON taking.Training = Training.TId
LEFT JOIN confirmation ON taking.Bid = confirmation.Bid
LEFT JOIN TrLocation ON taking.TrLocation = TrLocation.TrLId
LEFT JOIN Invoice ON taking.BId =Invoice.BId
LEFT JOIN couriertracking ON taking.BId = couriertracking.bId
LEFT JOIN SalesPerson ON taking.SId = SalesPerson.SId WHERE
taking.SubmitDateTime > DATE_SUB(NOW(), INTERVAL 2 MONTH)  AND IFNULL(taking.SId,0) > 0
ORDER BY taking.BId DESC LIMIT 10

我在出价栏尝试了索引,但查询时间仍然相同。我该如何优化查询?

1 个答案:

答案 0 :(得分:1)

由于您只有LEFT JOIN,并且LEFT JOIN只能添加更多行,因此您可以使用子查询限制从Taking表返回的行数。然后只需要将10行与其他表连接。如果任何JOIN将添加更多行,您仍然可以在外部查询中使用另一个LIMIT。

SELECT
    taking.BId,taking.calledDate Called, taking.calleduser Caller,
    taking.callerNotes, taking.Title, taking.FName, taking.ScName,
    taking.takingPhase, Training.TName, taking.TrDate,
    taking.SubmitDateTime, TrLocation.TrLocation trTrl, taking.STATUS,
    taking.DelegNum, taking.Tel, taking.Email,taking.Notes
FROM (
    SELECT taking.*
    FROM Taking taking
    WHERE taking.SubmitDateTime > DATE_SUB(NOW(), INTERVAL 2 MONTH)
      AND taking.SId > 0
    ORDER BY taking.BId DESC
    LIMIT 10
) taking
LEFT JOIN training Training ON taking.Training = Training.TId
LEFT JOIN confirmation ON taking.Bid = confirmation.Bid
LEFT JOIN TrLocation ON taking.TrLocation = TrLocation.TrLId
LEFT JOIN Invoice ON taking.BId =Invoice.BId
LEFT JOIN couriertracking ON taking.BId = couriertracking.bId
LEFT JOIN SalesPerson ON taking.SId = SalesPerson.SId
ORDER BY taking.BId DESC
LIMIT 10

请注意,taking.SId > 0与WHERE子句中的IFNULL(taking.SId,0) > 0具有相同的效果。 NULLSId的行与该条件不匹配。

但是 - 您仍应验证每个列上是否有用于连接的索引。对于此查询,您需要

上的索引
  • Training.TId
  • confirmation.Bid
  • TrLocation.TrLId
  • Invoice.BId
  • couriertracking.bId
  • SalesPerson.SId

其中一些看起来像主键。如果是这种情况,那么您就不需要为它们编制索引。

要找到Taking表的最佳索引并不那么简单。但12K行并不是那么多。只需使用SubmitDateTime上的索引即可。