2012-05-30 1 views
0

항목을 업데이트하는 것처럼 정렬 및 필터링 열을 처리 할 수있는 빠른 데이터베이스 스키마를 설계하고 싶습니다.자주 변경되는 항목에 가장 적합한 데이터베이스 스키마

  • 가 정확히 하나의 이름, 상태, 마지막 가입 날짜, 설명 및 한 위치
  • 이벤트에 해당하는 좌석의 수는 저장 이벤트가있다 :이를 위해

    나는 다음과 같은 시나리오를 만들어 참가자가
  • 을 subcribes 행사와 함께 모든 시간을 업데이트됩니다 모든 이벤트는 정확히 하나 개의 범주가 있습니다
  • 에만 범주
  • 이벤트로 나열 할 수있는 이벤트 이름, 상태 또는 날짜 테이블이 10 개 이상의 미오 항목

의 경우를 처리해야

  • 이벤트가 이름, 상태 또는 날짜 (XOR)으로 정렬 할 수 있습니다
  • (NO XOR)에 의해 필터링 할 수 있습니다 모든 테스트에서 나는 MySQL과 InnoDB 테이블을 사용했다. 또한 가능한 한 자주 여러 개의 삽입/업데이트/삭제를 사용하려고했습니다. 범주에 대한 하나의 이벤트에 대한 다른 하나 필터링은 먼저 내가이 개 테이블을 사용하려고 LIKE '% [단어] %'

    를 사용하여 수행됩니다. 색인은 카테고리 - 이름, 카테고리 - 상태 - 이름, 카테고리 - 날짜 - 이름 및 카테고리 - 날짜 - 상태 - 이름이었다. 이 경우 목록 작성, 필터링 및 정렬은 매우 빠르지 만 항목 삽입, 업데이트 또는 삭제는 매우 느립니다. 또한 색인을 다시 작성하는 데 너무 많은 시간이 걸리기 때문에 잠금 시간 초과가 발생했습니다.

    두 번째 시도는 카테고리, 이벤트 및 위치라는 세 가지 테이블을 갖는 것이 었습니다. 그러나 위치 테이블에 6mio 이상의 항목이 있으면 속도가 느려집니다. 나는 빠른 포획을위한 지수 때문에 생각한다. 100k 항목을 추가하는 데 ~ 272 초가 걸립니다. 위치의 인덱스는 기본 인덱스 ID지퍼 거리를했다

    다음 시도는 마지막 가입-날짜와 카운터에 대한 자신의 테이블을 생성하는 것입니다. 그러나이 날짜를 필터링하거나이 날짜를 정렬 할 수 있습니까?

    3 개 인덱스를 가지고 더 나은가요 같은 : 카테고리 이름, 카테고리 - 날짜, 카테고리-상태 또는 4 개 인덱스 카테고리 이름, 카테고리-상태 이름, 카테고리 최신 이름을 가진 내 솔루션입니다 카테고리 - 날짜 - 상태 - 이름 더 좋은 MySQL 용?

    필드 유형에 대해서도 생각하고 있습니다. 현재 이름에 VARCHAR을 사용했습니다. 그러나 모든 항목의 길이가 같으므로 가변 길이를 사용하는 대신 색인의 특정 위치로 이동하는 것이 더 빠르기 때문에 CHAR가 더 나은 것일 수 있습니다. 어떻게 생각해?

    위와 같은 시나리오를 지원하는 우수하고 빠른 데이터베이스 스키마가 어떻게 설계되어야하는지에 대한 조언이 있습니까?

  • +1

    인덱스는 고정 길이이므로 테이블 스캔의 경우에도 CHAR와 VARCHAR는 인덱스에 상관 없습니다. –

    +0

    나는 이것을 몰랐다. 고맙습니다. 모든 관련 열에 인덱스를 추가하여 테이블 스캔을 피하려고했습니다. –

    답변

    1

    색인은 고정 길이이므로 테이블 스캔의 경우에도 CHAR과 VARCHAR은 색인에 상관 없습니다.

    세부 사항없이 다른 확실한 답을 제공 할 수 없다고 생각합니다.나는 너에게 일반적인 조언을 해줄 수있다.

    클러스터 된 인덱스 (InnoDB 기본 키 또는 첫 번째 고유 키)에 삽입하지 마십시오. 클러스터형 인덱스는 자동 증가 형 열과 함께 자주 사용되므로 인덱스 만 추가되고 중간에는 아무 것도 삽입되지 않습니다. 이렇게하면 인덱스를 다시 작성하지 않아도됩니다.

    클러스터되지 않은 (2 차) 색인의 경우 색인이 클수록 삽입시 재 작성되어야하는 경우가 많습니다. 페이지가 가득 찰 때까지 삽입을 수행 한 다음 다시 작성합니다. 다시 말하지만, 색인의 끝에 추가하는 것이 좋습니다.

    인덱스는 삭제 표시 만되고 유휴 시간 동안 인덱스가 다시 작성되기 때문에 삭제는 성능에 영향을주지 않습니다.

    카디널리티가 낮은 열에서는 색인을 생성하지 않습니다. MySQL은이를 사용하지 않기 때문입니다. 인덱스는 필요할 때마다 추가해야하며 매번 장점과 단점을 고려해야합니다.

    다중 열 인덱스가 더 크고 (페이지에 맞는 항목이 적음) 더 많은 항목을 업데이트해야합니다. 다중 열 인덱스를 드물게 추가하십시오.

    MyISAM은 자주 읽는 것이 더 좋지만 잠금 경합 (테이블 잠금)으로 인해 다중 사용자 환경에서 자주 업데이트/삽입되는 경향이 있습니다. InnoDB는 잠금 경합 (행 잠금)이 적기 때문에 다중 사용자 환경에서의 업데이트가 더 좋지만 읽기에는 더 느립니다 (여전히 행 잠금이 필요함).

    필터링 LIKE '[word]%'은 인덱스를 사용할 수 있지만 LIKE '%[word]%' 형식의 필터링은 인덱스를 사용할 수 없습니다.

    자주 업데이트되는 시스템에서 인덱스는 업데이트 할 레코드를 선택할 때 중요한 역할을합니다. 인덱스가 좋을수록 잠금 경합이 적어 지므로 성능이 향상되고 교착 상태가 줄어 듭니다.

    JOIN이 많을수록 비용이 높아지고 쿼리 속도가 느려집니다. JOIN은 나쁘지 않지만 많은 행 (큰 결과 집합)의 JOIN은 느려질 수 있습니다.

    일부가 아닌 성능 관련주의 사항 : 이노와

    은, 당신이 교착 상태로 인해 실패 트랜잭션을 처리 할 준비를해야한다.

    +0

    기본 키가있는 테이블에 대해 클러스터형 인덱스에 삽입하지 않으려면 어떻게해야합니까? –

    +0

    InnoDB에만 클러스터 된 인덱스가 있습니다. 보통의 기본 키에 자주 삽입해야하는 경우에는 대리 auto_increment 기본 키를 사용하므로 항상 삽입하는 것이 아니라 클러스터 된 인덱스 끝에 추가합니다. –

    관련 문제