2010-01-11 6 views
29

나는 매우 자주 SELECT x, y, z FROM table WHERE x LIKE '%text%' OR y LIKE '%text%' OR z LIKE '%text%' 쿼리를 수행하는 MySQL 테이블을 가지고 있습니다. 어떤 종류의 색인이 일을 빠르게하는 데 도움이 될까요?여러 열에서 MySQL의 SELECT ... LIKE 쿼리 속도를 높이려면 어떻게해야합니까?

테이블에 몇 백만 개의 레코드가 있습니다. 검색 속도를 높이는 요소가 있다면 데이터베이스 파일과 디스크의 사용률에 영향을 미칠 것이며 INSERTDELETE 문장의 속도에 심각하게 영향을 미칩니 까?

업데이트을 (더 UPDATE는 지금까지 수행되지 않음) : 신속하게 게시 후, 나는 LIKE 쿼리에 사용되는 방법에 대한 정보와 토론을 많이 보았다; 해결책은이어야한다고 지적하고 싶습니다. 즉, 찾고있는 텍스트 앞에 % 와일드 카드를 붙이고 붙입니다. LIKE '%text%'을 사용해야합니다. 데이터베이스는 또한 보안과 같은 여러 이유로 로컬이어야합니다.

+4

이런 식으로 생각하면 완벽하게 비유 할 수는 없지만 요점을 잘 보여줍니다. 뒷쪽에 단어 색인이있는 책을 생각해보십시오. 단순한 단어 또는 동일한 처음 몇 글자로 시작하는 단어까지 찾으려면 아무런 문제가 없습니다. 그 책 색인을 사용하여 단어의 어느 곳에서든 "exe"문자를 포함하는 모든 단어를 검색하려고 할 때 어떤 일이 일어나는지 생각해보십시오. 색인은 꽤 쓸모가 없다. 그리고 당신은 그 단어를 찾는 실제적인 책을 읽을지도 모른다. 그것은 대략 당신이 mySQL에 부과하고있는 문제점입니다. – JohnFx

답변

51

색인은 왼쪽에서 시작하여 N 개의 문자를 색인화하여 색인을 생성하기 때문에 색인의 속도가 향상되지 않습니다. LIKE '% text %'를 할 때 텍스트 앞에 가변 수의 문자가있을 수 있기 때문에 색인을 사용할 수 없습니다.

당신이해야 할 일은 그와 같은 쿼리를 전혀 사용하지 않는 것입니다. 대신 MySQL이 MyISAM 테이블을 지원하는 FTS (Full Text Search)와 같은 것을 사용해야한다. MyISAM이 아닌 테이블에 대해서도 이와 같은 인덱싱 시스템을 만드는 것은 꽤 쉽습니다. 실제 테이블에 단어와 관련 ID를 저장하는 별도의 인덱스 테이블이 필요합니다.

+7

MySQL 5.6부터 전체 텍스트 검색 기능을 InnoDB에 추가 할 수 있습니다. – Sergio

+0

표의 언어와 마찬가지로 전체 텍스트 검색이 불가능한 경우가 있습니다. https://dev.mysql.com/doc/refman/5.7/en/fulltext-restrictions.html –

9

인덱스 할 수 하지 검색 기준은 와일드 카드로 시작되는 쿼리 속도를 사용할 수 :

LIKE '%text%'

인덱스 (그리고 선택에 따라 수 있습니다) 할 수있는 검색 용어를 사용 형태의 : 인덱스는 선도적 인 와일드 카드와 텍스트 매칭 도움이되지 않습니다

LIKE 'text%'

14

, 인덱스를 사용할 수 있습니다 :

LIKE 'text%' 

그러나 나는 그것을 잘라 내지 않을 것이라고 추측하고 있습니다. 이러한 유형의 쿼리의 경우 검색 할 수있는 레코드의 양을 확장하려는 경우 전체 텍스트 검색 공급자를 실제로 살펴야합니다. 내 선호하는 공급자는 Sphinx이며, 매우 완전한 기능/빠른 등도 있습니다. Lucene 또한 가치가있을 수 있습니다. MyISAM 테이블의 전체 텍스트 인덱스도 작동 할 것이지만, 상당한 양의 쓰기가있는 데이터베이스에 대한 MyISAM을 궁극적으로 추구하는 것은 좋은 생각이 아닙니다.

+0

MySQL 5.6 이상에서는 InnoDB 테이블과 함께 사용할 수도 있습니다. https://dev.mysql.com/doc/refman/5.7/en/fulltext-restrictions.html –

7

보고있는 필드가 비어 있거나 상수가 포함되어있는 경우 같은/rlike와 함께 색인을 사용하여 쿼리 속도를 향상시킬 수 있다고 덧붙입니다.

그런 경우 고정 값으로 "and"절을 추가하여 색인을 사용하여 방문한 행을 제한 할 수있는 것처럼 보입니다.

대개 태그가 많이 포함되어 있지 않은 거대한 테이블에서 '태그'를 검색하려고했습니다.

SELECT * FROM objects WHERE tags RLIKE("((^|,)tag(,|$))" AND tags!=''

당신이 태그에 색인이있는 경우가 검색되는 행을 제한하는 데 사용되는 것을 볼 수 있습니다.

+0

이것은 놀랍게도 아주 좋은 대안이며, 나는이 방법으로 칼럼을 색인 할 수있었습니다. – Kennysmoothx

6

아마 mysql5.1을 mysql5.7로 업그레이드 할 수 있습니다.

나는 약 70,000 개의 레코드가 있습니다. 그리고 SQL 다음 실행

select * from comics where name like '%test%'; 

이 mysql5.1에 2000ms 걸립니다. mysql5.7 또는 mysql5.6에서는 200ms이 필요합니다.

관련 문제