使用ORDER BY和HAVING时加速MySQL查询

时间:2013-05-06 14:55:42

标签: php mysql

我有一个拥有一堆游戏市场订单的数据库。我对数据库的意图是低买高卖,所以我所做的就是搜索任何可以赚钱的产品。我输入起点和终点,然后检查数据库中是否有在起始位置待售的产品,并检查任何匹配且有利润的买单的终点。

现在我有大约750k列表,处理查询大约需要8秒。当我减少行数时,花费的时间更少。一旦数据库已满,我可能会有超过500万条目,我需要弄清楚如何加快查询速度。我知道当我拿出HAVING和ORDER BY时,查询需要大约0.25秒/秒。还有另一种方法可以在mySQL中执行此操作,还是应该找到在PHP中执行此操作的方法?任何帮助,将不胜感激!

这是我的问题:

    SELECT DISTINCT  
    f.orderID as fOrderID,
    f.typeID as fTypeId,
    f.solarSystemID as fSystemId,
    f.regionID as fRegionId,
    f.price as fPrice,
    f.volRemaining as fVolRemain,
    f.bid as fBid,
    f.reportedTime as fReportedTime,
    t.orderID as tOrderID,
    t.typeID as tTypeId, 
    t.solarSystemID as tSystemId,
    t.regionID as tRegionId,
    t.price as tPrice,
    t.volRemaining as tVolRemain,
    t.bid as tBid,
    if(((f.volRemaining < t.volRemaining)),
      ((f.volRemaining * t.price) - (f.price * f.volRemaining)), 
      ((t.volRemaining * t.Price) - (f.price * t.volRemaining))) as profit,
    t.reportedTime as tReporedtTime
    FROM marketData as f
    JOIN marketData as t on t.typeID = f.typeID 
    WHERE f.regionID = 10000001
    AND t.regionID = 10000030
    AND f.bid = 0
    AND t.bid = 1
    GROUP BY f.orderID
    HAVING profit > 1000000
    ORDER BY profit DESC
    LIMIT 100       

MarketDB Layout(不包括我现在没有使用的9个附加列):

prim-unique                        indexed
+-------------------------------------------------------+
| orderID | regionID | stationID | typeID | bid | price |
+-------------------------------------------------------+ 
| 12345   |  223344  |  334455   |  13    |  0  | 22.43 |
| 12543   |  298474  |  348993   |  13    |  1  | 24.55 |   
| 24574   |  273646  |  392273   |  13    |  0  | 19.32 |
+-------------------------------------------------------+

EDITED: 添加说明:

id  select_type  table   type    possible_keys    key    key_len  ref              rows    Extra
1   SIMPLE       f       ALL     typeID           NULL   NULL     NULL             761338  Using where; Using temporary; Using filesort
1   SIMPLE       t       ref     typeID           typeID 8        market.f.typeID  76      Using where

1 个答案:

答案 0 :(得分:2)

看起来该表应该有2个索引。一个索引包括(regionID,bid,typeID),可能按此顺序,以及第二个索引(typeID)。第一个索引将用于快速扫描f以查找与条件匹配的记录并检索typeID(它位于索引中)。第二个索引将在t上用于连接。我不确定它为什么不使用较大的索引同时包含where子句,但它可能会随着MySQL的更高版本而改变。

根据您的实际数据模式,您可以通过同时创建多个变体来稍微调整第一个索引,只需尝试6个不同的可能订单,并运行解释计划以查看哪个使用索引。然后简单地删除未使用的索引。

注1: 拥有这两个索引会减慢表上的插入和删除速度,但我希望这个连接查询的速度更大,特别是没有索引。

注2: 减少表中的列数也会有所帮助,但不能解决连接的缩放问题。