2011-09-21 2 views
0

MySQL에서 category_id, subcategory_id 및 zipcode가있는 매우 큰 테이블 (3M 레코드 이상)을 쿼리하고 있습니다. 우편 번호는 DB에 10 자일 수도 있고 그렇지 않을 수도 있습니다.MySQL 첫 번째 문자열의 인덱스

목적은 지정된 zip의 특정 반경 내에있는 모든 cat/subcat 항목을 가져 오는 것입니다. 하나의 지정된 5 자리 우편 번호 목록을 반환하는 함수가 있습니다. 이 목록은 다음

SELECT whatever 
FROM tblName 
WHERE cat_id = 1 
AND subcat_id = 5 
AND LEFT(zip,5) IN (11111,22222,33333,44444,55555) 

내가 CAT_ID, subcat_id 및 우편에 복합 인덱스를 가지고 ... 그래서처럼 내 쿼리에 공급되지만, 우편 어떤 경우에는 10 자이를 던질 수있는. LEFT (zip, 5)을 어떻게 든 색인 할 수 있습니까?

+0

는이 쿼리에 대한 쿼리 계획을 가지고 적이 있습니까? 그게 어떻게 currenlty working.Instructions 다른 인덱스에 대해 생각하기 전에 그 정보를 가지고 있어야 유용합니다. –

+0

아니요, 인덱스에 함수를 사용할 수 없습니다. Oracle과 PostgreSQL에서는 가능하지만 MySQL에서는 그렇지 않습니다. – Johan

+0

"쿼리 계획"이란 EXPLAIN ... 쿼리를 실행한다는 의미입니까? 나는 그것에 대해 생각하지 않았다. 감사. @ 조한 : 나는 오라클에 대해 생각하고 있었다. 오랫동안 PL/SQL을 사용해 왔고,이 아이디어가 가능해 보였다. – Don

답변

1

모든 여분의 자릿수가있는 일반 5 자리 zip 및 열이 있어야하며 SQL에서 정상적으로 처리해야합니다. 당신이 이야기하는 것을 할 수있는 방법이 있지만 이것이 가장 효율적인 해결책입니다.

0

Zip의 LEFT (5) 만 인덱싱 할 수 있을지는 의심 스럽지만, 가능하다면 테이블에 여분의 열을 만들고 ZIP LEFT (5)로 업데이트 한 다음 해당 열을 인덱싱합니다. 내 성능을 향상시키기 위해

1

당신이 인덱스를 사용하려는 경우에 쿼리 변경 :

SELECT whatever 
FROM tblName 
WHERE cat_id = 1 
AND subcat_id = 5 
AND ( zip LIKE '11111%' 
    OR zip LIKE '22222%' 
    OR zip LIKE '33333%' 
    OR zip LIKE '44444%' 
    OR zip LIKE '55555%') 

또 다른 옵션은 테이블 (정말 마지막 옵션이어야한다)를 비정규 화하는 것입니다 그와 함께 여분의 필드를 추가는 5 왼쪽을 포함 우편 번호의 문자. 은 그럼 당신은 할 수 있습니다 :

SELECT whatever 
FROM tblName 
WHERE cat_id = 1 
AND subcat_id = 5 
AND LEFTzip5 IN (11111,22222,33333,44444,55555) 

필드 leftzip5에 인덱스를 넣어하는 것을 잊지 마십시오.

+0

감사합니다. 나는 이것에 대해 생각했다. 의사 데이터 (주소 등)를 상속받은 테이블이고 zip은 비효율적 인 varchar (255)입니다. 나는 테이블을 작게 만들기 위해 LEFT (x, 5)의 char (5)를 만드는 것에 대해 생각했다 ... 지금은 3M 레코드이고 거의 900MB이다. – Don

1

직접 질문에 대답하려면 : 예, 왼쪽 (우편 번호, 5)으로 색인을 생성 할 수 있습니다.

alter table tblName add index (zip(5)); 

그리고 당신은 쿼리가 인덱스를 사용 할 수 있도록하려면 모든 열 검색 :

alter table tblName add index (cat_id, subcat_id, zip(5)); 
관련 문제