안드로이드 앱 개발 프로젝트1

9일차 - 데이터 삽입 알고리즘 최적화

원준킹 2021. 1. 19. 18:33

오늘 한 것

 

- 데이터베이스 메모리 누수 현상이 발생할 수 있는지 이제와서 알았다.

 close()로  SQLiteDatabase 랑 cursor의 사용이 끝날 때 매번 닫아줘야함.

예외처리로 처리하는 방법도 있다고 하지만 그냥 수동으로 일일히 닫아주는게 당장은 깔끔한듯.

 

- 작업 수행 후 바로 닫으면 다음에 못 쓰니 어디서 닫을지 고민하다 그냥 onDestroy에서 닫기로 정함. 안드로이드 구글 문서에서도 onDestroy에서 사용하지 않는 자원 처리를 권고.

stackoverflow.com/questions/12801602/android-sqlite-leaked

 

Android SQLite leaked

i having problem with sql handler A SQLiteConnection object for database '/data/data/.../databases/queueManager' was leaked! Please fix your application to end transactions in progress properly a...

stackoverflow.com

 

- select EXISTS 로 데이터의 존재 여부를 파악하는게 select로 검색 후 데이터 개수가 0보다 많은지 검사하는 것 보다 효율적

    - stackoverflow.com/questions/5264658/is-exists-more-efficient-than-count0

 

Is EXISTS more efficient than COUNT(*)>0?

I'm using MySQL 5.1, and I have a query that's roughly of the form: select count(*) from mytable where a = "foo" and b = "bar"; In my program, the only thing that it checks is whether this is zer...

stackoverflow.com

    - exists 의 경우 탐색중 데이터 하나라도 발견시 종료와 동시에 값을 리턴

    - select는 전위 탐색

    - select .. LIMIT 1 조건을 추가하면 아마 성능은 똑같을 듯?

 

이 분 말씀으로는 이게 가장 빠르다고 하신다

 

- 어라.. 시간이 더 오래 걸린다. 25초 정도 걸림.

- 삽입할 데이터가 없어도 동일하게 25초 걸림.

- 예상하기론 쿼리를 매 파일마다 수행시켜서 더 오래 걸리는 듯?

- 쿼리 한번으로 데이터를 전부 가져와 일일히 비교하는 것 보다 쿼리를 일일히 보내는게 비효율적인 듯.

- 쿼리 한번으로 모든 입력 데이터와 db의 데이터를 비교해서 입력 데이터에서 db 데이터를 제외한 결과를 출력하는게 BEST 같음.

- 쿼리를 찾으러 떠나보자..

 

 

- 여러개 데이터 한번에 입력

 

 

- 테이블 간 값 비교를 위해 temptable을 따로 만들었다

 

- 입력 파일 데이터를 테이블에 넣고 기존 테이블과 비교하는 방법

temptable의 location 컬럼에 있는 데이터가 datatable의 location 컬럼에 있는 데이터 중에 없으면 temptable에서 해당 데이터를 선택해라

 

 

- 알고리즘 개선 요약

    1. 데이터베이스를 업데이트할때 해당 경로 내의 모든 파일의 경로를 temptable의 location 컬럼에 저장한다.

    2. 기존 datatable과 temptable의 location 컬럼을 비교해서 datatable에 없는 데이터들을 구한다

       (temptable - datatable = 새로운 데이터)

    3. 새로운 데이터들을 대상으로만 데이터베이스를 업데이트한다.

 

- 결과 : 데이터베이스에 아무 것도 없는 상태에서 2346개의 파일을 업데이트할 시 27초로 7일차의 기록인 14초보다 두배 가량 걸렸다 ..

다만 업데이트할 것이 없는 상태에선 4초의 시간이 걸렸으며 소량의 파일을 추가해도 4초 언저리에 작업이 완료되므로 본래의 목적은 달성.

데이터베이스에 삽입하는 시간 자체는 매우 짧은데 안드로이드에서 돌아가는 루프가 더 많아지니까 첫 작업이 길어지는 듯. 

27초면 엄청 길긴 하지만 다량의 파일을 한 번에 삽입하는 경우가 많지 않으니 Asynctask에서 게이지가 차오르는 형태로 진행과정을 사용자에게 보여주며 인내를 요구하는 것은 큰 부담은 아닐거라고 예상 중.

 

 

++

모든 파일의 경로가 아니라 mp4로 끝나는 파일의 경로만 temptable에 저장시 27초->22초, 4초->2초

724/2346 -> 724/724 

 

 

 여담

 

- 생각해보니 태그 데이터 관리를 매우 멍청하게 하고있었음을 깨달았음.

    - 태그 테이블을 따로 만들어서 데이터 id, 태그와 1대1 대응하는 정수값으로만 간단하게 관리 가능한데 문자열 포함방식으로 구현했음

 

    - 당장 기능에 문제는 없고 성능도 괜찮으니 후에 성능 개선의 욕심이 생길때 엎어보기 도전하자. 지금은 할 의욕이 안남ㅋ.. 

 

- cursor는 다 close() 해줬는데 SQLiteDatabase 는 close() 했다간 액티비티간 이동 시 먹통이 된다. 일단 남겨둠.

 

 

내일 할 것

- 대망의 Asynctask 이전 작업

    - 일단 파일 데이터 삽입 작업만 이전

    - 후에 검색 작업도 이전

- SQLiteDatabase close()로 닫아주기

 

 

 

 

참고

 

 

onDestroy 과정이 오래걸리고 다음 액티비티 호출이 빨리 이뤄지면 두 과정이 겹쳐 오류가 나는 경우가 있다고함. 나중애 참고.

 

blog.naver.com/PostView.nhn?blogId=huewu&logNo=110081631223

 

안드로이드 onDestroy 와 Handler

개발자가 스스로 테스트까지 다 수행하지 않고, 별도의 검증팀과 함께 일하면서 좋은 점이 뭘까요? 뭐 여러...

blog.naver.com

 

 

리소스 생성과 제거를 onCreate<->onDestroy 같이 대칭되게 수행하는 것을 강조하는 글.

 

programmingfbf7290.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0Activity-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

안드로이드 액티비티(Activity) 생명주기 총정리

: 해당 포스트는 액티비티 생명주기에 대한 기본적인 내용을 안다는 가정 하에 내용을 진행한다. : 다른 액티비티가 일부만 가리면 onPause()가 호출되고 전체를 가리면 onStop()이 호출된다. 디바이

programmingfbf7290.tistory.com

 

 

룸의 존재를 이제 알아버림. 지금 프로젝트에 적용하려면 뒤집어 엎어야하기 때문에 다음 프로젝트에 써보자..

leveloper.tistory.com/161

 

[Android] 룸(Room) 지속성 라이브러리

룸(Room)이란?  안드로이드 앱에서 SQLite 데이터베이스를 쉽고 편리하게 사용할 수 있도록 하는 기능이다. SQLite 위에 만든 구글의 ORM(Object-relational mapping)이다. 룸을 사용하면 앱의 단일 정보 소스

leveloper.tistory.com