Teradata 레코드에서 내보낸 대용량 4TB 텍스트 파일이 있는데 파일에 몇 개의 레코드(= 내 경우에는 행)가 있는지 알고 싶습니다.
이 작업을 어떻게 빠르고 효율적으로 수행할 수 있습니까?
답변1
이 정보가 아직 별도의 파일에 메타데이터로 존재하지 않고(또는 데이터에 포함되어 있거나 데이터가 파생된 시스템에 대한 쿼리를 통해 사용 가능) 사용 가능한 일부 설명의 인덱스 파일이 없는 경우 가장 빠른 방법 수량을 계산하기 위해철사wc -l
파일에 사용 하면 됩니다 .
정말 더 빨리 할 수는 없습니다.
수량을 계산하다기록파일에서 사용된 레코드 구분 기호를 알아야 하며 유사한 방법을 사용하여 awk
이를 계산해야 합니다. 마찬가지로, 이 정보가 아직 다른 곳에 메타데이터로 저장되어 있지 않은 경우, 원본 시스템을 쿼리하여 이 정보를 얻을 수 없는 경우, 기록 자체가 파일에 열거 및 정렬되지 않은 경우.
답변2
awk와 wc 사이의 속도 테스트는 다음과 같습니다.
67G 테스트.tsv
time awk 'END {print NR}' test.tsv; time wc -l test.tsv
809162924
real 2m22.713s
user 1m46.712s
sys 0m19.618s
809162924 test.tsv
real 0m20.222s
user 0m9.629s
sys 0m10.592s
다른 파일 72G Sample.sam
time awk 'END {print NR}' Sample.sam; time wc -l Sample.sam
180824516
real 1m18.022s
user 1m5.775s
sys 0m12.238s
180824516 Sample.sam
real 0m22.534s
user 0m4.599s
sys 0m17.921s
답변3
awk
및 와 같은 줄 기반 유틸리티를 사용하면 안 됩니다 sed
. 이 유틸리티는 read()
입력 파일의 각 행에 대해 시스템 호출을 발행합니다(참조:답변왜 그렇습니까). 행이 많으면 성능이 크게 저하됩니다.
파일 크기가 4TB이므로 행이 많은 것 같습니다. 따라서 (내 시스템에서는) 호출당 바이트만 읽기 때문에 wc -l
많은 read()
시스템 호출을 수행합니다. 16384
그럼에도 불구하고 이는 awk
합계에 비해 개선이 될 것입니다 sed
. 자신만의 프로그램을 작성하지 않는 한 가장 좋은 방법은 아마도
cat file | wc -l
cat
각 시스템 호출이 (내 시스템에서) 바이트 덩어리를 읽고 파일에서 직접이 아니라 파이프에서 더 많은 바이트를 방출하기 때문에 이것은 cat에 쓸모가 없습니다 . 그러나 각 시스템 호출은 가능한 한 많은 데이터를 읽으려고 시도합니다.131072
read()
wc -l
cat
답변4
또한 대용량 VCF 텍스트 파일에 대한 속도 비교도 수행했습니다. 이것이 내가 찾은 것입니다:
216GB VCF 텍스트 파일(단일 SSD)
$ time wc -l <my_big_file>
16695620
real 1m26.912s
user 0m2.896s
sys 1m23.002s
$ tail -5 <my_big_file>
$ time fgrep -n <last_line_pattern> <my_big_file>
16695620:<last_line_pattern>
real 2m10.154s
user 0m46.938s
sys 1m22.492s
$ tail -5 <my_big_file>
$ LC_ALL=C && time fgrep -n <last_line_pattern> <my_big_file>
16695620:<last_line_pattern>
real 1m38.153s
user 0m45.863s
sys 0m51.944s
마침내:
$ time awk 'END {print NR}' <my_big_file>
16695620
real 1m44.074s
user 1m11.275s
sys 0m32.780s
결론 1:
wc -l
SSD가 가장 빠른 것 같습니다.
216GB VCF 텍스트 파일(HDD 8개로 구성된 RAID10)
$ time wc -l <my_big_file>
16695620
real 7m22.397s
user 0m10.562s
sys 4m1.888s
$ tail -5 <my_big_file>
$ time fgrep -n <last_line_pattern> <my_big_file>
16695620:<last_line_pattern>
real 7m7.812s
user 1m58.242s
sys 3m12.355s
$ tail -5 <my_big_file>
$ LC_ALL=C && time fgrep -n <last_line_pattern> <my_big_file>
16695620:<last_line_pattern>
real 4m34.522s
user 1m26.764s
sys 1m58.247s
마침내:
$ time awk 'END {print NR}' <my_big_file>
16695620
real 6m50.240s
user 2m37.574s
sys 2m43.498s
결론 2:
wc -l
다른 사람들과 동등하게 보입니다.- 후속 시간도 더 낮은 시간을 표시하므로 더 낮은 시간은
LC_ALL=C && time fgrep -n <last_line_pattern>
캐싱으로 인한 것일 가능성이 높습니다wc -l
.