MySql-糟糕的性能

MySql-糟糕的性能,mysql,Mysql,我试图在一个有50万行的表上运行一个相对简单的查询。这只是一个小片段,我用它来测试我得到的值是否正确。问题是这个查询需要20多分钟才能完成,即使对于500000条记录来说,速度也异常缓慢 DROP VIEW IF EXISTS view_temp_sortie_stats; CREATE VIEW view_temp_sortie_stats AS SELECT server_id, session_id, ucid, role, sortie_id, ( SELECT

我试图在一个有50万行的表上运行一个相对简单的查询。这只是一个小片段,我用它来测试我得到的值是否正确。问题是这个查询需要20多分钟才能完成,即使对于500000条记录来说,速度也异常缓慢

DROP VIEW IF EXISTS view_temp_sortie_stats;
CREATE VIEW view_temp_sortie_stats AS
SELECT server_id, session_id, ucid, role, sortie_id, 
    (
        SELECT COUNT(sortie_id)
        FROM raw_gameevents_log 
        WHERE sortie_id = l.sortie_id AND server_id = l.server_id AND session_id = l.session_id AND target_player_ucid = l.ucid AND event = "HIT"
    ) AS HitsReceived
FROM raw_gameevents_log l
WHERE ucid IS NOT NULL AND sortie_id IS NOT NULL
GROUP BY server_id, session_id, ucid, role, sortie_id;

SELECT * FROM view_temp_sortie_stats;
这是我的桌子:

接下来,我尝试为服务器id、会话id、出击id添加索引,看看是否会有所改进—这花了10多分钟才应用并超时。所以我无法添加它们

这似乎异常缓慢,添加索引或执行此查询不应该花费这么多时间

我的innodb_buffer_pool_大小是5GB,但在运行这些查询时,mysqld进程只消耗300mb内存

我在Windows Server 2012 R2标准上运行,内存为12 GB,CPU是Intel Haswell的2倍,所以我应该看到mysql的性能比这要好得多

没有其他人连接到此MySql实例,也没有其他操作正在发生

编辑-这里解释了查询

有人知道可能出了什么问题吗

EDIT2-部分修复

通过谷歌搜索,我发现了为什么添加索引要花很长时间——原始查询仍然在后台运行了2个多小时。一旦我终止了查询,添加索引大约需要30秒

现在,当我运行上面的查询时,它需要27秒——这肯定是一个巨大的改进,但对于500000条记录来说,这仍然是相当缓慢的。以下是新的查询解释计划:

您的子查询是:

    SELECT COUNT(sortie_id)
    FROM raw_gameevents_log 
    WHERE sortie_id = l.sortie_id AND server_id = l.server_id 
    AND session_id = l.session_id AND target_player_ucid = l.ucid 
    AND event = "HIT"
SELECT server_id, session_id, ucid, role, sortie_id, [...]
FROM raw_gameevents_log l
WHERE ucid IS NOT NULL AND sortie_id IS NOT NULL
GROUP BY server_id, session_id, ucid, role, sortie_id;
主要查询是:

SELECT server_id, session_id, ucid, role, sortie_id, [...]
FROM raw_gameevents_log l
WHERE ucid IS NOT NULL AND sortie_id IS NOT NULL
GROUP BY server_id, session_id, ucid, role, sortie_id;
让我们从子查询开始。计数可以依赖于任何东西,因此我们不必为选择字段而烦恼。WHERE字段:

    WHERE sortie_id = l.sortie_id AND server_id = l.server_id 
    AND session_id = l.session_id AND target_player_ucid = l.ucid 
    AND event = "HIT"
创建索引时,先创建常量字段,然后创建其他字段:

CREATE INDEX subqindex ON raw_gameevents_log(
    event,
    sortie_id, server_id, session_id, target_player_ucid
)
然后,主查询:

WHERE ucid IS NOT NULL AND sortie_id IS NOT NULL
GROUP BY server_id, session_id, ucid, role, sortie_id;
这里你需要一个索引

ucid, sortie_id, server_id, session_id, role
最后,您可以尝试摆脱子查询(即使优化器可能已经在这方面做了很好的工作):


不幸的是,很多事情可能是错误的-我建议您尝试DBA stackexchange。我不知道mysqltuner是否可以在Windows上运行(我认为在必要的情况下,您可以在另一台机器上的瘦VM上运行它,并让它连接到windows2012服务器),但是有很多调整变量。表行格式可能与此有关。至少试着发布查询的解释,看看瓶颈实际在哪里:
EXPLAIN选择服务器id、会话id、ucid、角色、出动次数id(…等等)按服务器id、会话id、ucid、角色、出动次数id分组您试图读取/获取什么?它是一个平面表,包含所有服务器上记录的所有游戏事件。我试图计算一个玩家在空中飞行时被击中的次数。@LSerni我用查询解释更新了这个问题。按该顺序在(服务器id、会话id、出击id、ucid、角色)上添加一个索引,并按相同顺序重写
分组。多个索引!=多列索引。