http://docs.blackberry.com/ko-kr/developers/deliverables/37457/SQLite_database_performance_1554270_11.jsp
http://docs.blackberry.com/ko-kr/developers/deliverables/37457/
컴퓨터와 비교하여 휴대용 단말기는 SQLite 데이터베이스에 대해 매우 제한된 환경을 제공합니다. BlackBerry 스마트폰에서 최적의 성능을 얻으려면 다음 제약 조건을 고려해 봅니다.
동적 메모리 한도는 16MB입니다. 이 한도는 SQLite 데이터베이스에서 스키마 및 트랜잭션을 위한 내부 데이터 구조를 저장하는 데 사용할 수 있는 RAM의 양을 의미합니다. SQLite 데이터베이스가 열리면 전체 데이터베이스 스키마가 메모리에 로드되어 데이터베이스가 닫힐 때까지 유지됩니다.
SQL 쿼리의 최대 크기는 1MB입니다.
한 번에 열 수 있는 데이터베이스의 최대 수는 약 50개입니다. Database API는 동일한 데이터베이스에 대한 여러 연결에 대해 메모리를 효율적으로 사용하기 위해 공유된 캐시 모드를 사용합니다.
한 번에 SQLite 데이터베이스와의 읽기/쓰기 연결 하나만 가능합니다. 다른 데이터베이스 연결은 읽기 전용입니다.
Database.createBlobOutputStream 및 Database.createBlobInputStream 메소드를 사용하여 BLOB를 읽고 쓰는 경우, SQLite에 대해 사용 가능한 메모리에서는 사용자가 사용할 수 있는 BLOB의 크기를 제한하지 않습니다. 따라서 결과 세트의 한도가 1MB로 설정되지 않습니다.
Database.getCacheUsed, Database.getSchemaUsed 및 Database.getStatementUsed 메소드를 사용하여 각 데이터베이스 연결에 대한 메모리 사용을 추적할 수 있습니다.
BlackBerry 스마트폰에서 SQLite는 서비스로 실행됩니다. 데이터베이스 작업에서는 Java와 원시 코드 간에 데이터를 전송하기 위해 런타임 브리지를 사용합니다. 런타임 브리지를 통해 전송될 수 있는 데이터의 최대 양은 1MB입니다. 런타임 브리지는 데이터베이스 작업의 우수한 성능을 제공할 수 있지만 올바르게 사용되지 않으면 성능을 저하시킬 수도 있습니다.
데이터 삽입 또는 업데이트를 위해 준비된 문을 만들 경우 Statement.executeInsert 또는 Statement.executeUpdate 메소드를 사용하여 런타임 브리지의 호출 수를 줄여야 합니다. 이 메소드는 네이티브 코드에서 다음 작업을 수행합니다.
결과 세트를 반환하지 않는 쿼리를 실행하고 매개 변수를 연결하지 않는 경우에는 Database.executeStatement 메소드를 사용해야 합니다. 이 메소드를 사용하면 원시 코드에서 다음 작업을 수행하여 런타임 브리지의 호출 수를 줄여 줍니다.
Statement.getCursor 메소드를 사용하여 결과 세트를 반환하는 쿼리를 실행하는 경우에는 Statement.setCursorBufferSize 메소드를 사용하여 지정된 행 번호를 미리 가져올 수 있습니다. 이 방식은 런타임 브리지 사용을 줄여 줍니다. 커서가 버퍼링된 세트에서 이동할 경우 일련의 새 행들을 자동으로 가져옵니다. Statement.getCursorBufferSize 메소드를 사용하여 커서가 버퍼링하는 행의 수를 검색할 수 있습니다.
다른 쿼리에서 키로 사용하기 위해 정수 값을 검색하는 경우에는 Statement.getIntegers 및 Statement.getLongs 메소드를 사용할 수 있습니다. 이 메소드는 정수 열 검색을 단순화하고 최적화합니다.
다음 지침을 고려해 보십시오.
모범 사례 | 설명 |
---|---|
적절한 저널 모드 사용 | 기본적으로 트랜잭션을 기록하기 위해 롤백 저널이 사용되지만, 그 대신 미리 쓰기 로그를 사용하도록 선택할 수도 있습니다. 미리 쓰기 로그는 향상된 동시성을 제공하며 데이터베이스에 쓰는 작업에서 읽는 것을 차단하지 않기 때문에 대부분의 경우 롤백 저널보다 빠릅니다. 그러나 미리 쓰기 로그는 더 많은 파일 핸들을 사용합니다. 미리 쓰기 로그에서는 오랜 기간 동안 유지되는 파일 핸들을 3개까지 사용하는 반면 롤백 저널은 하나만 사용하고, 트랜잭션을 쓰는 동안에는 2개를 쓰는 경우도 있습니다. 저널링 모드를 미리 쓰기 로그로 변경하려면 SQL 문 "PRAGMA journal_mode = WAL;"을 실행합니다. |
테이블에 대한 가벼운 안전 제약 조건 고려 | 데이터 무결성이 문제되지 않는다면 Pragma 명령을 사용하여 저널을 지정하지 않고 동기화 모드를 끄는 것을 고려해 봅니다. 예를 들어, PRAGMA journal_mode=OFF 및 PRAGMA synchronous=OFF와 같습니다. |
테스트 | 대용량 스키마를 갖는 데이터베이스를 만들거나 대용량 BLOB를 삽입하려는 경우, 사용할BlackBerry 스마트폰에서 데이터베이스를 테스트하여 단말기의 메모리가 적절한지 확인해야 합니다. |
데이터를 가능한 한 적게 저장 | SQLite 데이터베이스 처리 시간의 대부분은 저장소에서 읽고 쓰는 데 소비됩니다. 일반적으로 데이터가 적을수록 읽기/쓰기 횟수가 줄어듭니다. SQLite 데이터베이스 엔진은 자주 액세스하는 데이터베이스 페이지를 캐시합니다. 데이터를 더 적게 저장하면 SQLite 데이터베이스 엔진에서 요청 받은 데이터를 상대적으로 속도가 늦은 저장소 액세스 대신 캐시에서 더 빨리 검색하게 될 가능성이 높아집니다. |
명시적 트랜잭션을 사용하는 그룹 문 | 명시적 트랜잭션을 사용하지 않는 경우에는 사용자가 실행한 각 문에 대해 트랜잭션이 생성됩니다. 이 기본 동작은 비효율적입니다. 각 문의 저널 파일에 대한 열기, 다시 열기, 쓰기 및 닫기가 필요합니다. 명시적 트랜잭션을 사용하면 그룹 문을 사용하여 효율성을 높일 수 있습니다. 문의 그룹 주변에 Database.beginTransaction 및 Database.commitTransaction을 두어 하나의 트랜잭션에서 여러 문을 실행할 수 있습니다. |
효율적인 색인 만들기 | 색인은 테이블 검색에 필요한 시간을 크게 단축시킬 수 있습니다. 효과적인 색인을 만드는 방법은 다음을 참고하십시오.
|
행 크기 최소화 | 매우 넓은 열은 별도의 테이블로 저장할 것을 고려합니다. |
BLOB를 적절히 저장 | 데이터에 BLOB가 포함된 경우에는 createBlobInputStream 및 createBlobOutputStream을 사용하는InputStream 및 OutputStream 객체를 사용하여 읽고 써야 합니다. 또한 각 BLOB를 개별 테이블에 저장하는 것을 고려해 볼 수도 있습니다. BLOB가 용량이 매우 클 경우, 이들을 데이터베이스 외부의 파일로 저장할 수 있습니다(그런 다음 데이터베이스에 각 파일의 경로를 저장). 하지만 이 방식은 파일 이름 조회를 위한 오버헤드가 발생합니다. |
임시 테이블 사용 고려 | 스마트폰을 다시 시작한 후에도 데이터를 사용할 필요가 없으면 CREATE TABLE 대신 CREATE TEMP TABLE 문을 사용합니다. |
SQL 매개 변수 사용 | 형식이 동일한 일련의 문을 실행하려면 먼저 SQL 매개 변수를 사용하는 일반 문을 준비합니다. 변수 값을 통해 반복하고 각 반복 시 명명된 변수에 값을 연결하여 문을 실행할 수 있습니다. |
하위 쿼리 사용 안 함 | 일부의 경우, SQLite 데이터베이스 엔진은 임시 파일에 하위 쿼리 결과를 저장합니다. 그러면 처리가 느려질 수 있습니다. |
데이터베이스 조각 모음 | SQLite VACUUM 명령을 사용하여 데이터베이스를 조각 모음합니다. 그러면 데이터베이스 파일 크기도 줄어듭니다. |
테이블 선언 내 열 순서 고려 | SQLite 데이터베이스 엔진은 테이블 선언에서 정의된 순서대로 열을 검색하기 때문에 테이블 선언 안의 열 순서는 특히 색인이 없을 경우 성능에 영향을 미칩니다. 자주 액세스하는 소량의 데이터가 들어 있는 열은 자주 액세스하지 않는 대량의 데이터가 들어 있는 열 앞에 배치해야 합니다. |
대량 작업 메소드 사용 | 다음 대량 작업 메소드는 런타임 브리지의 사용을 효율적으로 만들어 줍니다.
자세한 내용은 SQLite를 서비스로 이해를 참조하십시오. |