2

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

现在我有大约 750k 个列表,处理查询大约需要 8 秒。当我有更少的行时,它花费的时间更少。一旦数据库已满,我可能会有超过 500 万个条目,我需要弄清楚如何加快查询速度。我知道当我取出 HAVING 和 ORDER BY 时,查询大约需要 0.25/s。在 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 布局(不包括我现在没有使用的 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 |
+-------------------------------------------------------+

编辑:添加说明:

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
4

1 回答 1

2

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

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

注意 1:拥有两个索引会减慢您对表的插入和删除速度,但我预计此连接查询的速度会成为一个更大的问题,尤其是在没有索引的情况下。

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

于 2013-05-06T15:57:00.917 回答