Select / order by desc / 限制查询速度

Select / order by desc / limit query speed

我发现这两个查询的速度差异很大;第一个在 0.3 秒内运行,第二个在 76 秒内运行。

第一个查询仅 select 键,而第二个查询 select 一个附加字段,它是一个 int(11)。我可以将第二个字段替换为任何其他字段,结果相同。出于某种原因,仅选择密钥要快得多? 谁能解释速度上的巨大差异?我被这个难住了。

Q1:

SELECT  ID 
FROM TRMSMain.tblcalldata  
WHERE  (
         CallStarted BETWEEN '2014/06/13' AND '2014/06/13 23:59:59') 
ORDER BY ID DESC LIMIT 0 , 50

Q2:

SELECT ID, Chanid 
FROMTRM SMain.tblcalldata  
WHERE (
       CallStarted BETWEEN '2014/06/13' AND '2014/06/13 23:59:59') 
ORDER BY ID DESC LIMIT 0 , 50

此致

我想你的 CallStarted 列有一个索引,ID 是主键。您的第一个查询可以对该索引进行所谓的范围扫描,并快速检索行标识,因为 InnoDB 上的二级索引也包括主键。

所以它最终只做了一点点工作。

您的第二个查询必须从主 table 中获取数据。特别是它必须获取 ChanID 变量。然后它必须对整个混乱进行排序,从末尾抓取 50 个值,并丢弃其余的排序。

执行延迟连接以获取额外的列。也就是说,只需对 ID 号进行排序,然后从 table 中获取您需要的其余数据。这样你只需要获取 50 行的数据。

像这样:

SELECT a.ID, a.Chanid, a.WhatEver, a.WhatElse
  FROM TRMSMain.tblcalldata a
  JOIN (
         SELECT ID
           FROM TRMSMain.tblcalldata
          WHERE CallStarted BETWEEN '2014/06/13' AND '2014/06/13 23:59:59'
          ORDER BY ID DESC
          LIMIT 0, 50
       ) b ON a.ID = b.ID 
 ORDER BY a.ID DESC 

你知道内部查询很快;你已经证明了这一点。 JOIN 只是利用这种速度(基于对索引的良好使用)来获取所需行的详细数据。

专业提示:避免 BETWEEN 用于 date/time 范围,因为如您所知,它无法很好地处理范围的末尾。这将同样有效并避免 59:59 废话。

 WHERE CallStarted >= '2014/06/13' 
   AND CallStarted <  '2014/06/13' + INTERVAL 1 DAY

它从 6 月 13 日午夜开始抓取记录,并在第二天的午夜(<)之前获取所有记录,但不包括(<)。