2016-01-19 26 views
0

我对我的数据库使用MySQL,并且在数据库端做了一些处理,以使我的应用程序更加轻松。获得性能并执行快速sql查询的最佳方法?

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

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

下面是一个例子:

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 团队使用playerSlot在1,2-计算,3,4,5或6,7,8,9,10 isWinner is the team by winner and winner

这只是1个算法,我还有很多其他的要执行。我的数据库是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 
+0

上述查询所说的“explain select ....”是什么意思? –

+0

通常应该说些什么?有2个主要的,1个派生的和1个依赖的子查询。我不知道如何阅读'解释选择...'数据。你可以解释吗? – user2707590

+0

只是将它们复制到问题中。 –

回答

0

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

+0

我应该在我的所有领域添加索引吗?我的意思是我如何继续知道在哪里添加索引? – user2707590

+0

@ user2707590不仅在将要用于连接的字段上应用索引。 –

+0

如果一个字段是主键或外键,我还应该添加一个索引吗? – user2707590

3

这很明显,索引不会帮你在这里¹,因为你想要全部数据来自两个表。一旦汇总,您甚至需要两次来自tbl_game_player的数据,一次不汇总。所以有数百万条记录要读取和加入。你的查询很好,我看不出真正改善它的方法。

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

所以你的选择在于查询外:

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

由1,你的意思是,即使我有主键或外键,我应该创建另一个索引呢? – user2707590

+0

大多数DBMS自动在主键和外键上创建索引。我也不知道MySQL是否也这么做。如果没有,那么是的,创建它们。 –

-1

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