需要帮助来计算超大MySQL表中所有列的失败百分比

时间:2013-09-03 12:10:42

标签: mysql sql sql-server r

我很难计算出我庞大的MySQL表中每列的失败百分比。这是一个关于小表的外观的例子:

假设TABLE1有5列和100行,
CREATE TABLE IF NOT EXIST TABLE1 (id VARCHAR(255) NOT NULL, col1 DOUBLE NOT NULL, col2 DOUBLE NOT NULL, col3 NOT DOUBLE NULL, col4 NOT DOUBLE NULL);

“col1”到“col4”的每一列都有自己的上限和下限,我需要找到“col1”到“col4”失败的百分比。以下是我如何运行计算的示例。

计算总行数并按列“id”分组
SELECT id, COUNT(*) FROM TABLE1 GROUP BY id;

计算col1,col2,col3,col4满足所有限制的行总数,并按列“id”分组
SELECT id, COUNT(*) FROM TABLE1 WHERE (col1 BETWEEN 0 AND 10) AND (col2 BETWEEN 10 AND 20) AND (col3 BETWEEN 20 AND 30) AND (col3 BETWEEN 30 AND 40) GROUP BY id;

计算不符合col1限制的行总数
SELECT id, COUNT(col1) FROM TABLE1 WHERE (col1 NOT BETWEEN 0 AND 10) GROUP BY id;

计算符合col1限制但不符合col2限制的行总数,按“id”分组
SELECT id, COUNT(col2) FROM TABLE1 WHERE (col1 BETWEEN 0 AND 10) AND (col2 NOT BETWEEN 10 AND 20) GROUP BY id;

计算符合col1,col2限制但不符合col3限制的行总数,按“id”分组
SELECT id, COUNT(col3) FROM TABLE1 WHERE (col1 BETWEEN 0 AND 10) AND (col2 BETWEEN 10 AND 20) AND (col3 NOT BETWEEN 20 AND 30) GROUP BY id;

计算符合col1,col2,col3限制但不符合col4限制的行总数,按“id”分组
SELECT id, COUNT(col4) FROM TABLE1 WHERE (col1 BETWEEN 0 AND 10) AND (col2 BETWEEN 10 AND 20) AND (col3 BETWEEN 20 AND 30) AND (col3 NOT BETWEEN 30 AND 40) GROUP BY id;

我编写了一个R脚本来执行上述5个查询,并将结果合并到一个数据框下。以下是R处理后的输出示例:
id,total_no_rows,yield,col1,col2,col3,col4
CATEGORY1,25,80%,2%,8%,4%,6%,0%
CATEGORY2,25,70%,6%,14%,2%,6%,2%
CATEGORY3,25,90%,5%,0%,5%,0%,0%
CATEGORY4,25,65%,20%,2.5%,2.5%,5%,5%

现在使用这种方法我可以很快得到小表的结果。但是如果表变得非常大,比如1000列和100万行,那么完成计算的时间大约是2小时,这是非常长的。

无论如何我可以加快计算速度吗?

  1. 我尝试过索引,但显然MySQL无法索引1000列。
  2. 尝试同时查询(一次10个查询)但没有太大改进。 (我顺便使用InnoDB)
  3. 我已经阅读了一些帖子,其中用户建议将表拆分为较小的块以加快查询执行速度。但是,我的原始数据管理不善(长篇故事),所有数据都转储到一个大文本文件中。因此,将原始数据划分为较小的块将是一个挑战。
  4. 如果您有任何其他方法可以解决此类问题,请与我们联系。

    编辑:
    看起来Mani的提议确实节省了大量时间来获得结果。但是,对于非常大的表(数千列和数百万行),完成查询的时间仍然大约需要10分钟。有没有办法进一步改善查询时间?

1 个答案:

答案 0 :(得分:0)

您可以使用案例并在单个选择匹配中查找所有可能的场景。这会减少你的时间。

例如

select id, count(*), 
sum(case when col1 between 0 and 10 then 1 else 0 end) col1_yes,
sum(case when (col1 not between 0 and 10) and (col2 between 0 and 10) then 1 
else 0 end) col1no_col2yes 
from table 
group by id;