2012-01-20 3 views
0

상황 : .Net 클라이언트 응용 프로그램 (C#, Mono)은 웹 서비스 (SOAP)에서 데이터를 다운로드하고이를 Sqlite DB에 저장합니다. DB 인터페이스는 Sqlite3.dll을 사용하는 System.Data.Sqlite입니다.System.Data.Sqlite (C#) vs. Sqlite (C) 성능

DB (130MB)에는 수십 개의 테이블이 있습니다. 하나의 테이블은 특히 크며 DB 크기의 90 %를 차지합니다 - 일부 BLOB 컬럼이있는 레코드는 10000 개입니다. (가장 큰 얼룩은 260K입니다.)

iPad에서 다운로드하는 데 22 분이 소요됩니다. DB에 실제 글을 주석 처리 할 때 약 11 분이 걸렸으므로 DB가 약 11 분 정도 걸리는 것처럼 보입니다. "DB"는 System.Data.Sqlite 위의 일부 레이어를 의미합니다. 세부 사항을 아직 모릅니다. 내가 아는 전부는 모든 DB 명령이 트랜잭션에 있고 단지 몇 가지 트랜잭션이 관련되어 있다는 것입니다. (트랜잭션은 문제가되지 않습니다.)

Sqlite 쉘을 사용하여 DB를 덤프하고 sqlite3_exec()를 덤프 된 문자열과 함께 호출하는 C 코드를 측정했을 때 (이 코드는 최적이 아닙니다), 50 초 (iPad). 그것은 sqlite C 코드가 DB를 매우 빠르게 생성 할 수 있음을 의미합니다.

또 다른 흥미로운 문제 : 다운로드는 테이블별로 구성되어 있습니다. 모든 테이블 (일부는 몇 MB가 있음)은 정상적으로 작동합니다. 한 번에 다운로드를 몇 가지 항목 (5 개)으로 재구성해야하는 가장 큰 테이블을 제외하고. 이 방법을 사용하지 않으면 다운로드가 실패하여 메모리가 부족합니다. 가장 가능성있는 설명은 메모리 단편화입니다. (모노는 GC에 문제가있어 좋은 메모리 정보를 제공하지 않습니다.)

내 생각에 다운로드 프로세스 자체가 문제의 더 작은 부분에 책임이 있습니다. 그것은 DB와 대략 동일한 크기를 다운로드합니다. 단편화가 문제가되어서는 안됩니다. 그러나 단일 스레드 조직은 대기 시간을 추가합니다.

그러나 가장 큰 문제는 애플리케이션의 데이터 처리입니다.

  • 그것은 여러 프로토콜 (HTTP, SOAP, XML)
  • 데이터 처리 System.Data.Sqlite 및 sqlite3.dll을 호출을 구문 분석 할 수있다. 할당, 마샬링 등이 포함됩니다.

나중에 더 많은 테스트를 수행 할 예정이지만, 지금은 아이디어를 요청하고 싶습니다. 예를 들어 System.Data.Sqlite와 원시 Sqlite의 성능 비교를 환영합니다. 아무도?

+1

흠, 모든 거래에 엄청난 양의 행을 추가 하시겠습니까? 아니면 조금 더 나누시겠습니까? 거대한 트랜잭션을 사용하는 경우 트랜잭션 로깅이 문제가 될 수 있습니다. –

+0

나는 그것에 대해 생각했다. 그러나 덤프 된 문자열을 사용하여 설명 된 테스트를 수행하십시오. 거기에있는 모든 것 (명령 1000 개, 덤프 문자열 자체는 약 130MB)은 단일 트랜잭션 내에 있습니다. 결과는 완벽합니다. –

+0

죄송하지만, 나는 아무것도 얻지 못했습니다 :) 결코 모바일 플랫폼에서 sqlite로 크기가 조정 된 트랜잭션을 시도하지 않았습니다. –

답변

1

저는 지난 며칠간 Mono.Data.Sqlite로 몇 가지 테스트를 수행했으며 삽입 성능이 끔찍하다는 것을 알았습니다.

C 상당의 초당 14,000 개의 인서트 만 보았는데 비해 C 상당의 인서트는 38,000 개에 불과합니다. 이것은 1,024,000 개의 행을 삽입하는 paramaterised 문을 사용하여 트랜잭션에 string, string, string, string, string, string, DateTime을 삽입하는 것입니다. (많은 행을 떨어 뜨리는 동일한 성능)

실제 ExecuteNonQuery와 C 및 C 모두 # 112000 (초당 문자열)을 생성하는 동일한 반복 횟수를 처리하므로 내 경우에는 문제가 모노에서 sqlite 함께 interop 처리하는 그러나 온다.

이러한 테스트는 MacOSX에서 수행되었으며 개선 될 수 있는지 확인하기 위해 유료 monotouch 라이센스가 없으므로 실제 장치를 사용하지 않았습니다.

+0

그게 내가 의심했던 것입니다. 고마워요. 더 많은 테스트를 수행 할 것이며 여기에 결과를 게시 할 것입니다. –

+0

나는 반응을 약속했지만 그 공간은 충분하지 않다. 간단히 말하면 .Net 래퍼의 오버 헤드는 매우 커서 많은 경우에이 오버 헤드는 SQLite 자체보다 훨씬 많은 시간이 걸립니다. –

+0

예. 우리가 삽입에 대해서만 말한다면, 바인딩 (paramaterised statement)을 사용하는 것을 꺼리는 것보다. 모든 매개 변수는 직렬화되고 정렬되어야합니다. 이 프로세스에는 몇 가지 할당이 포함됩니다. 요약하면, 매개 변수가없는 insert 문을 작성하면 코드가 훨씬 빨라집니다. –