【问题标题】:Best way to gain performance and do fast sql queries?获得性能并进行快速 sql 查询的最佳方法?
【发布时间】:2016-01-19 11:45:59
【问题描述】:

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

直到最近我的数据库有很多数据并且查询非常非常非常慢。

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

这是一个例子:

tbl_game

+--------------------------------------------------+ |编号 |赢家 |持续时间|结束于 | |--------+--------+---------+----------| | 1 | 1 | 1200 |时间戳| | 2 | 0 | 1200 |时间戳| | 3 | 1 | 1200 |时间戳| | 4 | 1 | 1200 |时间戳| +--------------------------------------------------+

获胜队的获胜者为 0 或 1 持续时间是游戏花费的秒数

tbl_game_player

+-------------------------------------------------- + |游戏ID |玩家ID |玩家插槽 |碎片 |死亡 | |--------+----------+------------+--------+-------- | | 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 我的真实表格中有更多细节,这只是为了概述。

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

这是一个例子:

+-------------------------------------------------- -------------------------------------+ |游戏ID |玩家ID |碎片 |死亡 |行动 |团队 |百分比 |是赢家 | |--------+----------+--------+--------+---------+-- ----+----------+----------|

行动 = 碎片 + 死亡 percent = (actions / sum(同队玩家的actions)) * 100 团队使用 1,2,3,4,5 或 6,7,8,9,10 中的 playerSlot 计算 isWinner 由队伍和获胜者计算

这只是一种算法,我还有很多其他算法要执行。我的数据库有 100 万多条记录,查询速度很慢。

这是上面的查询:

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

【问题讨论】:

  • 上述查询的explain select.... 是什么意思?
  • 此外,哈希键可能比索引更有帮助。不使用索引会使您的数据库真正更快,但只是在开始时。您能展示一下您是如何创建这些表格的吗?
  • 正常应该说什么?有 2 个主查询、1 个派生子查询和 1 个从属子查询。我不知道如何读取explain select... 数据。你能解释一下吗?
  • 只需将它们复制到问题中。
  • 我知道。它返回给我一个带有一些结果的表格,但我不知道如何使用这个结果来查找错误。

标签: mysql database algorithm


【解决方案1】:

很明显,索引在这里对您没有帮助¹,因为您需要两个表中的所有数据。您甚至需要两次来自tbl_game_player 的数据,一次聚合,一次不聚合。因此,有数百万条记录可供读取和加入。您的查询很好,我认为没有办法真正改进它。

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

所以您的选择不在查询范围内:

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

【讨论】:

  • 1,你的意思是即使我有主键或外键,我也应该在上面创建另一个索引?
  • 大多数 DBMS 会自动在主键和外键上创建索引。我不知道 MySQL 是否也这样做。如果没有,那么是的,创建它们。
【解决方案2】:

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

【讨论】:

  • 我应该在我的所有字段上添加索引吗?我的意思是我如何继续知道在哪里添加索引?
  • @user2707590 不仅在连接时使用的字段上应用索引。
  • 如果 ffield 是主键或外键,我还应该在上面添加索引吗?
  • 是的,但前提是使用关系。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2017-03-24
    • 2022-01-23
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 2010-09-22
    相关资源
    最近更新 更多