我有下面的查询需要大约50秒才能运行,有没有办法让它更快?我还没有做任何索引,并会在不久的将来尝试这样做,但我仍然是新的。问题不是使用索引。
Select stock.StockID As StockID,
stock.BinLocation As BinLocation,
stock.StockCode As StockCode,
stock.Descr As Descr,
stock.Currency As Currency,
stock.Notes As Notes,
stocklocations.Quantity As Quantity,
stocklocations.SLNID As SLNID,
stock.ConditionA As ConditionA,
stocklocationsname.SLN As SLN,
stock.DateAdded As DateAdded,
(Case When (stock.Currency = 'Euro') Then (1.05 * stock.unitprice)
When (stock.Currency = 'GBP') Then (1.24 * stock.unitprice)
When (stock.Currency = 'USD') Then (1 * stock.unitprice) End) As unitprice,
stock.DepName As DepName,
stockhistory.POID As POID,
stock.POID As POID1,
stock.PartNumber As PartNumber,
vender.VendorName As VendorName,
equiptype.EQName As EQName,
groupname.Name As Name
From ((((((stock
Join stocklocations On stock.StockID = stocklocations.StockID)
Join stocklocationsname On stocklocations.SLNID = stocklocationsname.SLNID)
Left Join stockhistory On stockhistory.SHID = (Select Min(stockhistory.SHID)
From stockhistory Where stockhistory.StockID = stock.StockID))
Left Join po On stockhistory.POID = po.POID)
Left Join vender On po.Vender = vender.VendorID)
Left Join equiptype On stock.EquipType = equiptype.EquipTypeID)
Left Join groupname On stock.GroupNameID = groupname.GroupNameID
Where stocklocations.Quantity > 0 And stock.Status <> 'obsolete'
答案 0 :(得分:1)
1)删除unuseful()并避免嵌套左连接
2)不要使用左连接中涉及的fo列,因为这种方式变成了内连接
3)而不是subselect尝试使用与stockhistory中的stockid相关的最小值的连接
Select
stock.StockID As StockID,
stock.BinLocation As BinLocation,
stock.StockCode As StockCode,
stock.Descr As Descr,
stock.Currency As Currency,
stock.Notes As Notes,
stocklocations.Quantity As Quantity,
stocklocations.SLNID As SLNID,
stock.ConditionA As ConditionA,
stocklocationsname.SLN As SLN,
stock.DateAdded As DateAdded,
Case When stock.Currency = 'Euro' Then 1.05 * stock.unitprice
When stock.Currency = 'GBP' Then 1.24 * stock.unitprice
When stock.Currency = 'USD' Then 1 * stock.unitprice End As unitprice,
stock.DepName As DepName,
stockhistory.POID As POID,
stock.POID As POID1,
stock.PartNumber As PartNumber,
vender.VendorName As VendorName,
equiptype.EQName As EQName,
groupname.Name As Name
From stock
Join stocklocations On stock.StockID = stocklocations.StockID
and stocklocations.Quantity > 0
And stock.Status <> 'obsolete'
Join stocklocationsname On stocklocations.SLNID = stocklocationsname.SLNID
Left Join (
Select stockhistory.StockID, Min(stockhistory.SHID)
From stockhistory
group by stockhistory.StockID ) t_h on t_h StockID = stockhistory.StockID
Left Join po On stockhistory.POID = po.POID
Left Join vender On po.Vender = vender.VendorID
Left Join equiptype On stock.EquipType = equiptype.EquipTypeID
Left Join groupname On stock.GroupNameID = groupname.GroupNameID
确保您对加入
中涉及的表和列也有适当的索引答案 1 :(得分:1)
您应该在stockhistory.StockID
上有一个索引:
ALTER TABLE stockhistory ADD INDEX (StockID);
这应该加快stockhistory
上的子查询。或者,由于您正在检索SHID
的最小值,因此您也可以在索引中包含该列:
ALTER TABLE stockhistory ADD INDEX (StockID, SHID);
添加索引不会创建任何限制或逻辑约束(唯一索引除外)。但是,正如MySQL文档中8.3 Optimization and Indexes中所述:
虽然为查询中使用的每个可能列创建索引很有吸引力,但不必要的索引会浪费空间并浪费时间让MySQL确定要使用的索引。索引还会增加插入,更新和删除的成本,因为必须更新每个索引。您必须找到适当的平衡,以使用最佳索引集实现快速查询。
确定要创建的索引是一门艺术。一个好的开始是使用EXPLAIN
调查查询执行情况,如8.8.1 Optimizing Queries with EXPLAIN。
答案 2 :(得分:0)
尝试不使用您在连接和FROM中写入的括号。
Select stock.StockID As StockID,
stock.BinLocation As BinLocation,
stock.StockCode As StockCode,
stock.Descr As Descr,
stock.Currency As Currency,
stock.Notes As Notes,
stocklocations.Quantity As Quantity,
stocklocations.SLNID As SLNID,
stock.ConditionA As ConditionA,
stocklocationsname.SLN As SLN,
stock.DateAdded As DateAdded,
(Case When (stock.Currency = 'Euro') Then (1.05 * stock.unitprice)
When (stock.Currency = 'GBP') Then (1.24 * stock.unitprice)
When (stock.Currency = 'USD') Then (1 * stock.unitprice) End) As unitprice,
stock.DepName As DepName,
stockhistory.POID As POID,
stock.POID As POID1,
stock.PartNumber As PartNumber,
vender.VendorName As VendorName,
equiptype.EQName As EQName,
groupname.Name As Name
From stock
Join stocklocations On stock.StockID = stocklocations.StockID
Join stocklocationsname On stocklocations.SLNID = stocklocationsname.SLNID
Left Join stockhistory On stockhistory.SHID = (Select Min(stockhistory.SHID) From stockhistory Where stockhistory.StockID = stock.StockID)
Left Join po On stockhistory.POID = po.POID
Left Join vender On po.Vender = vender.VendorID
Left Join equiptype On stock.EquipType = equiptype.EquipTypeID
Left Join groupname On stock.GroupNameID = groupname.GroupNameID
Where stocklocations.Quantity > 0 And stock.Status <> 'obsolete'
答案 3 :(得分:0)
没有它需要多长时间才能执行?
Left Join stockhistory On stockhistory.SHID = (Select Min(stockhistory.SHID)
From stockhistory Where stockhistory.StockID = stock.StockID))
如果需要5-6秒,那么您应该将StockID的最小SHID组转换为视图,然后首先加入视图,然后使用stockhistory本身来获取stockhistory.POID