2012-10-17 2 views
3

사람이 읽을 수있는 값을 하나의 열에 저장하고 같은 텍스트에 다른 문자와 공백을 뺀 조회를 위해 테이블을 사용합니다. 예를 들어 값 "Children 's Shows"는 조회 열에 "childrens-shows"로 표시됩니다.MySQL CONCAT의 '*'기호는 데이터베이스를 토스트합니다.

불행히도 해당 주 테이블은 그리 간단하지 않습니다. 역사적인 이유로 내가 직접 만들지 않았으므로 실행 취소하기가 어려울 수 있습니다. 조회 값은 실제로 주변의 별표와 함께 저장됩니다. '* childrens-shows *'. 별표가있는 메인 테이블 룩업 테이블 산세 별표에 참여하는 동안

그래서, 나는; CONCAT는 예컨대, 내가 즉석에서 추가 도움이 될 생각

SELECT * 
     FROM main_table m 
INNER JOIN lookup_table l 
     ON l.value = CONCAT('*',m.value,'*') 

... 그리고 테이블은 토스트였습니다. 무한 루프를 만들었거나 실제로 데이터를 망쳤는지 확실하지 않지만 테이블을 다시 응답하게하려면 ISP 백업이 필요합니다. '*'기호는 와일드 카드처럼 예약되어 있기 때문에 의심 스럽습니다. 그리고 데이터베이스에 자신의 팔꿈치를 핥는 것과 동일한 작업을 수행하도록 요청했습니다. 어느 쪽이든, 저는 데이터베이스를 죽일 수있는 놀라운 방법으로 주어진 답을 찾기 위해 '실험'하는 것을 주저합니다.

(a) 위의 내용이 실제로 데이터베이스에 수행 한 내용과 (b) 실제로 테이블에 가입해야하는 사람에게 미리 감사드립니다.

+0

+1은 db가 자신의 팔꿈치를 핥도록합니다. 또한 문제가 무엇인지 궁금 해서요. –

+0

'main_table'에 몇 개의 레코드가 있습니까? –

+0

당신의 조인은 두 테이블에 공통적으로 몇 가지 ID를 가져야한다고 생각합니다. 한도를 적용 해보십시오. –

답변

2

CONCAT을 사용할 때, mysql은 인덱스를 사용하지 않습니다. 이것을 확인하기 위해 EXPLAIN을 사용하되, 최근의 문제점은 큰 테이블에서 인덱스 된 컬럼이 있지만 키가 사용되지 않았다는 것입니다. 그러나 전체 테이블을 bork해서는 안됩니다. 그냥 느리게 만드십시오. 아마도 메모리가 부족하여 교체를 시작한 다음 중간에 추락했지만 로그를 확인하여 확인해야합니다.

그러나 근본 원인은 분명히 나쁜 표 디자인이며 해결책이있는 곳입니다. 이 문제를 해결할 수있는 모든 대답은 기껏해야 일시적 일 수 있습니다.

최상의 솔루션은이 데이터를 별도의 테이블로 옮기는 것입니다. '아동 쇼'는 카테고리와 같은 소리가 나며 많은 행에서 반복되는 데이터입니다. 내가 아는

SELECT * 
     FROM main_table m 
INNER JOIN lookup_table l 
     ON l.value = m.value 
    /* and optionally */ 
INNER JOIN categories cat 
     ON l.value = cat.id 
    WHERE cat.name = 'whatever' 

이 뭔가되지 않습니다 :이 작업을 수행 할 수 있기 때문에 이건 정말, 테이블에있는 모든 단일 행에 CONCAT을 실행하는 데에서 DB를 방지 할 것 '범주'테이블의 ID이어야한다 귀하가 귀하의 질문에 제공된 정보를 제공 할 수 있을지 모르지만, 실제로 정상적으로 처리되지 않은 DB를 변경하지 못하는 이유는 여기의 코드보다 더 중요합니다. 일을 올바른 방식으로 수행하기위한 자원이나 정치적 뒷받침이 없으면 장기간에 더 많은 비용이 드는 이런 두통이 결국 끝날 것입니다. 아마도 보스와 단어를위한 시간 :

관련 문제