我发现这两个查询之间的速度差异很大;第一个在0.3秒内运行,第二个在76秒内运行。
第一个查询仅选择键,而第二个查询选择另一个字段,即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
此致
答案 0 :(得分:2)
我认为您的CallStarted
列上有索引,而ID
是主键。您的第一个查询可以对该索引执行所谓的范围扫描,并快速检索行标识,因为InnoDB上的二级索引还包括主键。
所以它最终只做了一点工作。
您的第二个查询必须从主表中获取数据。特别是它必须获取ChanID
变量。然后它必须对整个混乱进行排序,从最后获取50个值,并丢弃其余的那些。
执行延迟联接以获取额外的列。也就是说,只需对ID号进行排序,然后从表中获取所需的其余数据。这样你只需要抓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
日期/时间范围,因为您知道它处理范围的结束很差。这也会表现良好并避免59:59
废话。
WHERE CallStarted >= '2014/06/13'
AND CallStarted < '2014/06/13' + INTERVAL 1 DAY
它从6月13日的午夜开始抓取记录,并在第二天的午夜时间内完成但不包括(<
)。