MySQL查询在/tmp中使用10G空间,并使用';错误代码:28-设备上没有剩余空间';但在本地应用程序上效果很好
我正在运行一个相当复杂的SQL语句,从一个包含原始数据的大表(3800万行)创建一个汇总表。(我正在尝试将当前、本季低、本季高、本周/月/季价格百分比一直为1美分的数据放入MySQL查询在/tmp中使用10G空间,并使用';错误代码:28-设备上没有剩余空间';但在本地应用程序上效果很好,mysql,sql,linux,opensuse,Mysql,Sql,Linux,Opensuse,我正在运行一个相当复杂的SQL语句,从一个包含原始数据的大表(3800万行)创建一个汇总表。(我正在尝试将当前、本季低、本季高、本周/月/季价格百分比一直为1美分的数据放入缓存表中,以便于以后查询。) 在price.time列上添加了一个索引后,我在local上成功地将其降到了0.6秒(之前花了30秒)。在prod(具有相同索引)上,它需要很长时间(30秒以上),然后失败,错误代码:28-设备上没有剩余空间。如果我在运行时观察df,我会看到空闲空间以大约3MB/s的速度从9.9G慢慢减少到9.6
缓存
表中,以便于以后查询。)
在price.time列上添加了一个索引后,我在local上成功地将其降到了0.6秒(之前花了30秒)。在prod(具有相同索引)上,它需要很长时间(30秒以上),然后失败,错误代码:28-设备上没有剩余空间。如果我在运行时观察df,我会看到空闲空间以大约3MB/s的速度从9.9G慢慢减少到9.6G。几分钟后,可用空间突然开始下降500MB/s,直到没有剩余空间,查询失败。在本地,可用空间中似乎没有任何光点,尽管我猜它可能太快了,以至于我的df
在一个while循环中看不到它
如果我尝试先创建一个包含子查询结果的表,也会出现磁盘占用行为:
INSERT INTO initial_cache (`time`, name, price)
SELECT
`time`,
name,
MIN(price) AS price
FROM price
WHERE `time` > 1493337600
GROUP BY `time`, name
你知道为什么我的查询需要这么多空间来运行吗?为什么它在prod上的表现会如此不同
谢谢 子查询在内存不足时往往会使用大量临时空间。 然而,有一部分有点多余:初始子查询之后的时间检查:重写该子查询(其中总和(1)很奇怪): 这可能相当于:
INSERT INTO cache (`time`, name, price, low, high, week, month, season)
SELECT
MAX(`time`) AS `time`,
name,
MIN(price) AS price,
MIN(price) AS low,
MAX(price) AS high,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS week,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS month,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS season
FROM price
WHERE `time` > 1498442022
GROUP BY name;
然而,由于外部查询的重写看起来很奇怪,我怀疑这是否就是您要寻找的结果:提供数据和预期结果以获得更好的答案。我没有解决这个问题,但我确实解决了它。我所做的是让程序插入数据,同时也将数据插入子查询形成的表中。然后我分别执行外部查询。现在我有了一种两级缓存。由于某些原因,这一切都可以正常工作,而不会占用磁盘空间。通过
cd/tmp验证您的/tmp是否在设备上;df-h.
作为添加。将只显示目录的diskYup的df stats,它位于/dev/root。。。使用的文件系统大小Avail Use%挂载在/dev/root 24G 13G 9.9G 56%/您的/tmp
分区已满,或者至少您尝试执行的任何操作都会耗尽可用空间。当操作正在进行时,请注意df-h
,因为我打赌你会看到它在一个分区中缩小到零。哇,你是对的。随着该操作的运行,它的使用速度大约为3MB/s,从9.9G空闲下降到9.3G空闲。然后它突然开始下降500MB/s,直到没有可用空间和错误。你知道为什么我的查询在运行时会占用这么多空间吗?我将更新问题。首先计算FROM中的查询,将其写入磁盘,然后外部进程开始执行:如果数据太多,请先在FROM中为查询创建一个临时表,甚至可以在该临时表上添加索引,然后使用该表的输出运行querySorry的第二部分,我应该举个真实的例子,我有点懒。在真正的查询中,周
现在是-1周,月
现在是-1个月,季节
是过去的一个特定时间点。因此,这些时间戳对于获取要放入缓存的数据是必需的。我将用更准确的内容更新问题。如果查询给出相同的结果,那么数据库设计有问题。您所说的“查询”是指哪些查询?
INSERT INTO cache (`time`, name, price, low, high, week, month, season)
SELECT
MAX(`time`) AS `time`,
name,
MIN(price) AS price,
MIN(price) AS low,
MAX(price) AS high,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS week,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS month,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS season
FROM
(SELECT
`time`,
name,
MIN(price) AS price
FROM price
WHERE `time` > 1498442022
GROUP BY `time`, name) AS tmp
GROUP BY name;
INSERT INTO cache (`time`, name, price, low, high, week, month, season)
SELECT
MAX(`time`) AS `time`,
name,
MIN(price) AS price,
MIN(price) AS low,
MAX(price) AS high,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS week,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS month,
SUM(CASE WHEN price = 1 THEN 1 ELSE 0 END) / SUM(1) AS season
FROM price
WHERE `time` > 1498442022
GROUP BY name;