2014-09-24 2 views
0

에서 파일에 쓰기 :만들기 선택하고 내가 아주 간단이 그루비 코드가 빠르게 그루비

sql.eachRow("""SELECT 
     LOOP_ID, 
     FLD_1, 
     ... 20 more fields 
     FLD_20 
     FROM MY_TABLE ORDER BY LOOP_ID"""){ res-> 

    if(oldLoopId != res.loop_id){ 
     oldLoopId = res.loop_id 
     fileToWrite = new File("MYNAME_${type}_${res.loop_id}_${today.format('YYYYmmDDhhMM')}.txt") 
     fileToWrite.append("20 fields header\n") 
    } 

    fileToWrite.append("${res.FLD_1}|${res.FLD_2}| ... |${res.FLD_20}\n"); 
} 

} 

이이 테이블에서 일을 선택하고 데이터베이스에 기록합니다. 각각의 새로운 loop_id에 대해 새로운 파일을 생성합니다. 문제는 50MB 파일을 작성하는 데 약 15 분이 걸린다는 것입니다.

어떻게 더 빨리 만들 수 있습니까? 대신 직접 append을 사용하는 BufferedWriter

+1

File.append는 작성기를 열고 파일의 끝으로 이동하여 한 줄을 씁니다. 이 대신 새 파일에 대한 작성자를 작성하고 여기에 작성하십시오 (새 작성자를 작성하기 전에 닫는 것을 잊지 마십시오). –

답변

1

시도 쓰기 :

sql.eachRow("""SELECT 
     LOOP_ID, 
     FLD_1, 
     ... 20 more fields 
     FLD_20 
     FROM MY_TABLE ORDER BY LOOP_ID""") { res -> 

    def writer 
    if (oldLoopId != res.loop_id) { 
     oldLoopId = res.loop_id 
     def fileToWrite = new File("MYNAME_${type}_${res.loop_id}_${today.format('YYYYmmDDhhMM')}.txt") 
     if (writer != null) { writer.close() } 
     writer = fileToWrite.newWriter() 
     writer.append("20 fields header\n") 
    } 

    writer.append("${res.FLD_1}|${res.FLD_2}| ... |${res.FLD_20}\n"); 

File::withWriter는 자동적으로 자원을 닫습니다,하지만 당신은 점점 모든 loop_id 및 가져 오는, 방법이 더 여행이 DB 작업을 수행해야 할 것입니다 그것을 사용하는 각각에 대한 데이터.


다음 스크립트

f=new File("b.txt") 
f.write "" 
(10 * 1024 * 1024).times { f.append "b" } 

실행 :

$ time groovy Appends.groovy 

real 1m9.217s 
user 0m45.375s 
sys 0m31.902s 

그리고 BufferedWriter 사용 :

w = new File("/tmp/a.txt").newWriter() 
(10 * 1024 * 1024).times { w.write "a" } 

실행 :

$ time groovy Writes.groovy 

real 0m1.774s 
user 0m1.688s 
sys 0m0.872s 
+0

시도가 빠르지 만 여전히 느립니다. 50MB의 데이터 당 4 분이 소요됩니다. 느린 커서를 지나가고있는 것일까 요? 어떻게 든 더 빠르게 만들 수 있습니까? –

+0

당신은 파일 쓰기에 속도를 체크하기 위해 주석을 달 수 있습니다. 그러나 느린 파일 쓰기가 거의 확실합니다. – Will

+0

모든 호출에 의해 공유되기 때문에 'def writer'가 클로저 외부로 나가면 안됩니다 ? – Tobia