我有以下查询,在销售表中的60,000记录上大约需要20秒。我知道ORDER BY和LIMIT导致了这个问题,因为当删除ORDER BY时,它会在0.10秒内返回。
我不确定如何优化此查询,任何想法?
解释输出在https://gist.github.com/anonymous/1b92fa64261559de32da
SELECT sale.saleID as id,
node.title as location,
sale.saleTotal as total,
sale.saleStatus as status,
payment.paymentMethod,
field_data_field_band_name.field_band_name_value as band,
invoice.invoiceID,
field_data_field_first_name.field_first_name_value as firstName,
field_data_field_last_name.field_last_name_value as lastName,
sale.created as date
FROM sale
LEFT JOIN payment
ON payment.saleID = sale.saleID
LEFT JOIN field_data_field_location
ON field_data_field_location.entity_id = sale.registerSessionID
LEFT JOIN node
ON node.nid = field_data_field_location.field_location_target_id
LEFT JOIN invoice
ON invoice.saleID = sale.saleID
LEFT JOIN profile
ON profile.uid = sale.clientID
LEFT JOIN field_data_field_band_name
ON field_data_field_band_name.entity_id = profile.pid
LEFT JOIN field_data_field_first_name
ON field_data_field_first_name.entity_id = profile.pid
LEFT JOIN field_data_field_last_name
ON field_data_field_last_name.entity_id = profile.pid
ORDER BY sale.created DESC
LIMIT 0,50
答案 0 :(得分:3)
可能,你什么都做不了。例如,在衡量绩效时,您是否正在查看返回第一个记录或整个结果集的时间?如果没有order by
,查询可以很快返回第一行,但您仍可能需要等待一段时间才能获得所有行。
假设比较有效,以下索引可能帮助:sale(created, saleId, clientId, SaleTotal, SaleStatus
。这是查询的覆盖索引,经过精心构造,因此可以按正确的顺序读取。如果这样可以避免最终排序,那么即使是获取第一行,它也应该加快查询速度。
答案 1 :(得分:2)
最小
ALTER TABLE `sale` ADD INDEX (`saleID` , `created`);
ALTER TABLE `invoice` ADD INDEX (`saleID`);
答案 2 :(得分:0)
指数优先。但是另一种涉及LIMIT的技术,例如使用分页,是使用值:页面的最后一行产生搜索下一页的起始值。
当您使用ORDER BY sale.created DESC
时,您可以猜出足够长的时间段:
WHERE sale.created > CURRENT_DATE() - INTERVAL 2 MONTH
创建必须的索引。