2010-03-23 2 views
2

상태 컬럼이있는 MySQL InnoDB 테이블이 있습니다. 상태는 '완료'또는 '처리 중'일 수 있습니다. 테이블이 커짐에 따라 상태 값의 .1 %는 '처리 중'이고 나머지 99.9 %는 '완료'됩니다. 이것은 '처리'에 대한 높은 선택성으로 인해 색인에 대한 훌륭한 후보자처럼 보입니다 ('완료'는 아님). 'processing'값만 인덱싱하는 상태 열에 대한 인덱스를 만들 수 있습니까? 나는 인덱스가 엄청난 양의 공간 인덱싱을 낭비하는 것을 원하지 않는다.하나의 MySQL 컬럼 값 인덱싱

+0

값이 "1"또는 "0"인 "처리"라는 비트 열로 변환하는 것이 더 쉬운 지 궁금합니다. 공간을 적게 차지합니다. (2 개 이상의 상태가없는 한) –

+0

좋습니다. 실제로 2 가지 이상의 상태가 있지만 단순화를 위해 단순화했습니다. – BrainCore

+0

"단순화를 위해 단순화했습니다."- 다른 이유로 몇 가지를 단순화하지 않는 한 괜찮습니다 .- – paxdiablo

답변

3

내가 어떤 표준 방법을 알고 아니에요 이렇게하려면 두 테이블을 사용하여 비슷한 문제를 해결해야합니다. ProcessingDone, 이전에는 색인이 있고 후자는없는 것입니다. 행 이제까지 processingdone에서 다시 전환하지 않는 것이 가정

, 여기 당신이 사용할 수있는 단계는 다음과 같습니다 당신이 레코드를 생성 할 때

  1. processing로 설정 컬럼으로 Processing 테이블에 삽입합니다.
  2. 완료되면 열을 done으로 설정합니다.
  3. Processing 테이블을 주기적으로 스윕하고 done 행을 Done 테이블로 이동합니다.

마지막 항목은 까다 롭습니다. 트랜잭션에서 삽입/삭제를 수행하여 트랜잭션이 올바르게 전송되도록하거나 고유 한 ID를 사용하여 이미 전송되었는지 감지 한 다음 Processing에서 삭제할 수 있습니다 (MySQL 트랜잭션 지원에 대한 경험이 없기 때문에 또한 옵션을 제공함).

그런 식으로 done 행의 99.9 % 중 일부만 색인을 생성합니다. 아직 행이 Done 표로 전송되지 않았습니다. 덧글에서 언급 한 바와 같이 processing의 여러 상태에서도 작동합니다 (항목은 done 상태에 도달했을 때만 전송되고 다른 모든 상태는 Processing 테이블에 유지됩니다).

효율성을 위해 별도의 테이블로 이전 한 기록 데이터 (다시 변경되지 않는 데이터)가있는 것과 비슷합니다. 두 테이블을 조인해야하기 때문에 done 및 비 done 행에 모두 액세스해야하는 일부 쿼리가 복잡해 지므로 절충안을 알아 두십시오.

0

더 나은 해결책 : 상태를 나타내는 문자열을 사용하지 마십시오. 대신 설명적인 이름 => 정수 값을 사용하여 코드에서 상수를 사용하십시오. 그런 다음 정수는 데이터베이스에 저장되고 MySQL은 문자열보다 빠르게 작동합니다.

난 당신이 사용하는 어떤 언어 모르겠지만 PHP 예를 들면 :

대신 당신이 지금 무슨의
class Member 
{ 
    const STATUS_ACTIVE = 1; 
    const STATUS_BANNED = 2; 
} 

if ($member->getStatus() == Member::STATUS_ACTIVE) 
{ 
} 

:

if ($member->getStatus() == 'active') 
{ 
} 
+0

답변 해 주셔서 감사합니다.문자열은 사실 ENUM이며, 이는 정수로 매핑된다는 것을 의미합니다. 당신의 제안은 유효한 질문이지만, 그것은 나의 질문의 근원에 도달하지 못합니다 : 그것은 꼭 필요한가? – BrainCore

관련 문제