为了测试,我使用了一个具有 4 列和大约 900 万条记录的文件。我使用了同一台服务器,该服务器是带有 SSD 和 1GB RAM 的 VPS。
column1 是一个具有约 10 个唯一值的列,并且所有列的组合的总唯一值数约为 4k。
在 MySQL 中,我使用一个定义为 table (column1、column2、column3、column4) 的表,没有索引。
数据格式:
column1,column2,column3,column4 column1,column2,column3,column4
AWK 脚本:
BEGIN {
FS = ",";
time = systime();
} {
array[$1]++; #first test
#array[$1 "," $2 "," $3 "," $4]++; #second test
}
} END {
for (value in array) {
print "array[" value "]=" array[value];
}
}
MySQL查询:
Query 1: SELECT column1, count(*) FROM log_test GROUP BY column1;
Query 2: SELECT column1, column2, column3, column4, count(*)
FROM log_test GROUP BY column1, column2, column3, column4;
如预期,AWK比MySQL慢。然而,当我运行第一个返回10行聚合数据的测试时,MySQL需要约7秒才能完成,而AWK需要约22秒。
我了解awk逐行读取并处理数据,因此我希望当我运行第二个输出4k行的测试时,AWK应该像第一个测试一样花费相同的时间,因为它仍然有相同数量的行要读取,并且没有进行更多的处理。然而,AWK需要约90秒,但只使用0.1%的内存,而MySQL需要约45秒,并使用3%的内存。
- 当它基本上读取相同的文件时,为什么AWK在测试2中比测试1花费更多的时间?
- 为什么AWK不使用更多的内存?awk是否将其值存储在硬盘上而不是内存中?
- 当它基本上也必须逐行读取表格时,为什么MySQL要快得多?
- 是否有更有效的方法来聚合这些数据?
log_test
(column1
varchar(20) DEFAULT NULL,column2
varchar(20) DEFAULT NULL,column3
varchar(20) DEFAULT NULL,column4
varchar(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 - Ballard