2011-12-19 2 views
3

네트워크 오버 헤드없이 효율적이고 매우 빠른 액세스를 위해 일부 정보를 다른 시스템에 배포하려고합니다. 데이터는 관계형 스키마에 존재하며 엔티티 간의 관계에 "조인"해야한다는 요구 사항이지만 데이터베이스에 쓰는 요구 사항은 아닙니다 (오프라인으로 생성됩니다).빠른 읽기 전용 포함 된 "데이터베이스"?

SQLite가 성능을 제공한다는 확신이 있었지만 RDMBS는 근본적인 수준에서는 적합하지 않은 것 같습니다. 조인은 인덱스 조회 비용으로 인해 매우 비싸고 읽기 전용 컨텍스트에서는 불필요한 오버 헤드입니다 엔티티는 파일 오프셋의 형태로 서로 직접 참조를 저장할 수 있습니다. 이 방법으로 파일 찾기를 위해 인덱스 조회가 전환됩니다.

내 옵션에는 어떤 것들이 있습니까? 데이터베이스가 실제로 내가 원하는 것을 설명하는 것 같지 않습니다. 나는 Neo4j에 대해 알고 있지만 자바에 내 앱을 포함시킬 수는 없다.

TIA!

  • 데이터의 크기가 최대 1GB 될 것입니다, 나는 정말 옵션이 아닙니다 그래서 메모리에 데이터를 유지하는 PHP를 사용하고 있습니다 :

    편집, 주석을 응답합니다. 나는 지속적으로 디스크로가는 것을 피하기 위해 OS 버퍼 캐시에 의존 할 것이다.

  • 예제는 15 개의 혼합 유형 필드와 특정 제조사가있는 제품을 카테고리 테이블에 등록하는 쿼리가있는 Product 테이블입니다.
  • 솔루션은 일종의 플랫 파일이어야합니다. 내 요구를 충족시키는 소프트웨어가 이미 있는지 궁금합니다.

@ 마크 윌킨스 : 성능 문제를 측정

. 필자의 상황에서는 2ms IO 바인딩 쿼리를 Memcache에 5ms CPU 바운드 호출로 대체하는 것이 용납되지 않습니다 ... 예를 들어, categories 테이블에는 부모 및 자식 범주가 포함 된 500 개의 레코드가 있습니다. 다음 쿼리는 디스크 IO가없는 ~ 8ms가 걸립니다. SELECT 1 FROM categories INNER JOIN 범주 B on b.id = a.parent_id. 일부 단순한 조인리스 쿼리는 매우 빠릅니다.

+0

이것은 관계형 스키마이며 관계에 참여해야하지만 관계형 데이터베이스를 사용하고 싶지 않다고 말하고 있습니까? 플랫 파일을 사용하지 않는 이유는 무엇입니까? – Oded

+0

"DB"의 예제와 대략적인 크기를 지정하십시오. – CAFxX

답변

1

필요로하는 쿼리 유형에 대한 귀하의 목표에 대해 명확하지 않을 수도 있습니다. 그러나 파일 오프셋을 다른 데이터에 저장하는 부분은 유지 및 디버그하기가 매우 쉬운 과도한 솔루션 인 것처럼 보입니다. 거기에 도움이 될 수있는 도구가있을 수 있지만 내 의심은 당신이 당신 자신의 대부분을 작성 결국 것입니다. 나중에 다른 사람이 와서 디버그하고 가정용 파일 형식을 찾아내는 경우 더 많은 작업이 필요했습니다.

하지만 처음 생각한 성능 문제가이 시점에서 예측되었거나 실제로 측정되었는지 궁금해 할 것입니다. 관계형 형식의 데이터로 테스트를 실행하여 실제 속도를 확인하십시오. 조인은 거의 항상 더 많은 파일 읽기를 필요로합니다 (앞에서 언급 한 것처럼 2 진 검색을 수행 한 다음 연관된 레코드 정보를 얻은 다음 해당 레코드를 찾음). 이것은 처음에는 4 개 또는 5 개 이상의 디스크 작업을 수행 할 수 있습니다. 그러나 카테고리 테이블 (OP에서)에서는 일반적으로 충돌하는 경우 캐시 된 상태가 될 수 있습니다. 이것은 내 생각에 완전한 추측이지만, 많은 경우 카테고리의 수가 상대적으로 적습니다. 이 경우에 전체 범주 테이블과 인덱스가 OS에 의해 메모리에 캐시 된 상태로 유지 될 수 있으므로 매우 빠른 조인이 발생합니다.

성능이 실제로 문제가되는 경우 다른 가능성은 denormalize the data 일 수 있습니다. 카테고리 예에서는 카테고리 값/이름을 복제하고 각 제품 레코드와 함께 저장합니다. 결과적으로 데이터베이스 크기가 커지지 만 내장 데이터베이스 (there are a number of possibilities)를 계속 사용할 수 있습니다.현명하게 완료되면 여전히 합리적으로 잘 관리 될 수 있으며 하나의 조회/탐색과 하나의 읽기로 전체 개체를 읽을 수있는 기능을 제공 할 수 있습니다.

1

일반적으로 가장 빠른 방법은 데이터를 비정규 화하여 JOIN 및 다른 다중 테이블 조회를 피하는 것입니다.

SQLite를 사용하면 모든 종류의 것을 사용자 정의하고 필요에 맞게 조정할 수 있습니다. 예를 들어, 하나의 스레드를 통해서만 액세스하거나, 메모리 캐시 크기를 늘리거나, 인덱스를 사용자 정의하거나, 불필요한 메타 데이터를 사용하지 않도록 사용자 정의 빌드를 수정하거나, 디버깅 할 때 모든 뮤텍스를 비활성화하십시오.

당연히 데이터베이스가 필요한 것으로 가정합니다.

+0

비정규 화는 데이터 크기를 늘리는 정도 때문에 옵션이 아닙니다. – Scott

+0

정규화가 옵션이 아닐지라도 나열된 글 머리 기호 항목을 다시 반복 해 볼 것입니다. (여전히, 데이터의 부적절한 부분을 de-normalize하고 약간의 공간 비용으로 주요 속도 향상). 사용자 정의에 맞게 SQLite 빌드 + pragma 설정 등. EXPLAIN을 사용하여 모든 쿼리를 분석하고 쿼리 플래너를 사용하여 속도를 향상 시키십시오. – NuSkooler