获得性能和快速SQL查询的最佳方法是什么?

时间:2016-01-19 11:46:00

标签: mysql database algorithm

我将MySQL用于我的数据库,并在数据库端进行一些处理,以便我的应用程序更容易。

我以前的查询非常快,直到最近我的数据库有很多数据,查询非常非常慢。

我的应用程序主要进行统计,并且有很多相关的数据库来获取数据。

以下是一个例子:

tbl_game

+-------------------------------------+
|     id | winner | duration| endedAt |
|--------+--------+---------+---------|
|      1 |      1 |    1200 |timestamp|
|      2 |      0 |    1200 |timestamp|
|      3 |      1 |    1200 |timestamp|
|      4 |      1 |    1200 |timestamp|
+-------------------------------------+
赢得比赛的球队获胜者为0或1 持续时间是游戏的秒数

tbl_game_player

+-------------------------------------------------+
| gameId | playerId | playerSlot | frags | deaths | 
|--------+----------+------------+-------+--------|
|      1 |      100 |          1 |    24 |     50 | 
|      1 |      150 |          2 |    32 |     52 | 
|      1 |      101 |          3 |    26 |     62 | 
|      1 |      109 |          4 |    48 |     13 | 
|      1 |      123 |          5 |    24 |     52 | 
|      1 |      135 |          6 |    30 |     30 | 
|      1 |      166 |          7 |    28 |     48 | 
|      1 |      178 |          8 |    52 |     96 | 
|      1 |      190 |          9 |    12 |     75 | 
|      1 |      106 |         10 |    68 |     25 | 
+-------------------------------------------------+

详细信息仅适用于ID为1的第一款游戏 1个游戏有10个玩家位置,其中1-5位= 0队,6-10 = 1队 我的真实表中有更多细节,这只是为了概述。

所以我需要计算所有游戏中每个玩家的统计数据。我创建了一个视图来实现这一点,当我的数据很少时,它可以正常工作。

以下是一个例子:

+--------------------------------------------------------------------------+
| gameId | playerId | frags | deaths | actions | team | percent | isWinner |
|--------+----------+-------+--------+---------+------+---------+----------|

行动=死亡+死亡 百分比=(动作/总和(同一队员中的球员的动作))* 100 团队使用1,2,3,4,5或6,7,8,9,10中的playerSlot计算 isWinner由团队和获胜者计算

这只是一个算法,我还有很多其他的算法。我的数据库是1百万+记录,查询非常慢。

以下是对上述内容的查询:

SELECT
    tgp.gameId,
    tgp.playerId,
    tgp.frags,
    tgp.deaths,
    tgp.frags + tgp.deaths AS actions,
    IF(playerSlot in (1,2,3,4,5), 0, 1) AS team,
    ((SELECT actions) / tgpx.totalActions) * 100 AS percent,
    IF((SELECT team) = tg.winner, 1, 0) AS isWinner
FROM tbl_game_player tgp
INNER JOIN tbl_game tg on tgp.gameId = tg.id
INNER JOIN (
    SELECT
        gameId,
        SUM(frags) AS totalFrags,
        SUM(deaths) AS totalDeaths,
        SUM(frags) + SUM(deaths) as totalActions,
        IF(playerSlot in (1,2,3,4,5), 0, 1) as team
    FROM tbl_game_player
    GROUP BY gameId, team
) tgpx on tgp.gameId = tgpx.gameId and team = tgpx.team

3 个答案:

答案 0 :(得分:3)

很明显,索引在这里没有帮助你¹,因为你需要来自两个表的所有数据。您甚至希望来自tbl_game_player的数据两次,一旦汇总,一旦未汇总。因此,有数百万条记录可供阅读和加入。你的查询很好,我认为没办法改进它。

¹当然,您应该始终在主键和外键上有索引,因此DBMS可以在连接中使用它们。 (例如,tbl_game(tgp.gameId)上应该有一个索引。

因此,您的选项不在查询范围内:

  • 硬件(显然)。
  • 将团队的计算列添加到tbl_game_player,因此至少在查询时保存其评估。
  • 分区。每个团队一个分区,因此聚合可以单独计算。
  • 预先计算的数据:添加一个保存总和的表tbl_game_team;用触发器填充它。因此,您不必在查询中计算聚合。
  • 数据仓库表:创建一个包含完整结果的表。用触发器或间隔填充它。

答案 1 :(得分:0)

设置索引可以加快查询速度。如果有很多结果,查询可能需要一段时间才能运行,这绝对是一个开始。

答案 2 :(得分:-1)

对于大型数据库,Mysql INDEX在速度问题上非常有用,可以在表格中创建索引,以便更快地找到数据。有效率的。所以必须创建索引,你可以在这里了解更多关于MYsql索引http://www.w3schools.com/sql/sql_create_index.asp

相关问题