You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL JOIN关联currencies_rates表查询rate报table is full错误排查

问题描述

我尝试通过JOIN语法从currencies_rates表中提取rate字段,但运行查询时抛出错误"[HY000][1114] The table '' is full",不清楚写法存在什么问题,相关查询语句如下:

SELECT
    game_id,
    u.country,
    COUNT(*) as count,
    SUM(IF(currency = 'EUR', (bet * cr.rate), bet)) as total_bets
FROM
    games_stats
    INNER JOIN users u on games_stats.user_id = u.id
    JOIN currencies_rates cr ON cr.to = 'EUR'
WHERE
    u.country IS NOT NULL
GROUP BY
    game_id,
    user_id
ORDER BY
    total_bets DESC;

涉及的相关表结构如下:

  • currencies_rates表:
    currencies_rates表结构
  • games_stats表:
    games_stats表结构
问题原因
  1. 核心错误:JOIN缺少两表关联条件,触发笛卡尔积导致数据量爆炸
    关联currencies_rates表时,仅写了cr.to = 'EUR'的过滤条件,没有添加currencies_rates和games_stats的字段关联逻辑(正确逻辑应该是通过games_stats.currency = cr.from匹配对应货币对EUR的汇率)。这种写法会让两表结果做全量笛卡尔积:如果games_stats和users关联后有100万条数据,currencies_rates里to='EUR'的记录有30条,最终中间结果会直接膨胀到3000万条,数据量超过临时表内存/磁盘限制时就会抛出table is full错误。
  2. GROUP BY字段不匹配
    SELECT子句中查询了u.country字段,但GROUP BY里仅写了game_id, user_id,如果数据库开启了ONLY_FULL_GROUP_BY模式,这个写法本身会直接抛出语法错误,最终统计结果也会不符合预期。
修正后的SQL
SELECT
    gs.game_id,
    u.country,
    COUNT(*) as count,
    SUM(IF(gs.currency = 'EUR', gs.bet, gs.bet * cr.rate)) as total_bets
FROM
    games_stats gs
    INNER JOIN users u ON gs.user_id = u.id
    -- 补充关联逻辑:用统计表的货币字段匹配汇率表的源货币,同时限定目标货币为EUR
    INNER JOIN currencies_rates cr 
        ON gs.currency = cr.`from` 
        AND cr.`to` = 'EUR'
WHERE
    u.country IS NOT NULL
GROUP BY
    gs.game_id,
    u.country, -- 把SELECT中出现的非聚合字段加入GROUP BY
    gs.user_id
ORDER BY
    total_bets DESC;
补充说明
  • 多表关联时建议给所有表加简短别名,查询字段前加表前缀限定归属,避免字段歧义引发的报错。
  • from、to属于SQL保留字,作为字段名使用时建议用反引号包裹,避免SQL解析错误。
  • 如果修正关联逻辑后仍然出现table is full错误,可以检查数据库临时表目录的磁盘剩余空间,适当调大tmp_table_size、max_heap_table_size参数的阈值,提升临时表可用内存上限。

内容的提问来源于stack exchange,提问作者Dmitry Ivanoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:48:18