2009-12-15 4 views
0

아래의 쿼리가 있습니다 ... 작동하지만 매우 느리게 실행됩니다. 누군가 실행 시간을 향상시키기위한 몇 가지 팁을 줄 수 있기를 희망 했습니까?느린 mysql 쿼리. 어떤 팁?

SELECT tb_clients.*, tb_clients_phone_fax.* 
FROM tb_clients, tb_clients_phone_fax 
WHERE tb_clients.client_id=tb_clients_phone_fax.client_id 
AND MATCH (client_company,client_description,client_keywords) AGAINST ('test') > 0 
AND CONCAT(client_address,' ',client_city,', ',client_state,' ',client_zip) LIKE '%brooklyn%' 
LIMIT 10; 

편집 :

CREATE TABLE `tb_clients` (
    `client_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `client_company` varchar(254) NOT NULL, 
    `client_address` varchar(254) NOT NULL, 
    `client_street` varchar(254) NOT NULL, 
    `client_city` varchar(254) NOT NULL, 
    `client_state` varchar(254) NOT NULL, 
    `client_zip` varchar(45) NOT NULL, 
    `client_email` varchar(254) NOT NULL, 
    `client_website` varchar(254) NOT NULL, 
    `client_description` text NOT NULL, 
    `client_keywords` text NOT NULL, 
    PRIMARY KEY (`client_id`) USING BTREE, 
    FULLTEXT KEY `client_company` (`client_company`,`client_description`,`client_keywords`) 
) ENGINE=MyISAM AUTO_INCREMENT=68347 DEFAULT CHARSET=latin1; 

CREATE TABLE `tb_clients_phone_fax` (
    `client_phone_fax_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `client_id` int(11) unsigned NOT NULL, 
    `client_phone_1` varchar(45) NOT NULL, 
    `client_phone_2` varchar(45) NOT NULL, 
    `client_phone_3` varchar(45) NOT NULL, 
    `client_fax_1` varchar(45) NOT NULL, 
    `client_fax_2` varchar(45) NOT NULL, 
    `client_fax_3` varchar(45) NOT NULL, 
    PRIMARY KEY (`client_phone_fax_id`) USING BTREE 
) ENGINE=MyISAM AUTO_INCREMENT=33944 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC; 
+0

'% brooklyn %'은 검색 매개 변수를 나타낼 수 있습니까? – ChaosPandion

+1

각 필드의 데이터 유형과 어떤 필드가 색인인지 보여주는 것이 도움이 될 것입니다. – philfreo

+0

예, % brooklyn % '은 검색 매개 변수를 나타냅니다. – mike

답변

2

tb_clients.client_id 및 tb_clients_phone_fax.client_id 색인되어야한다 : 여기

테이블 정보입니다.

하지만 주요 문제는 두 문자열 비교, MATCH 및 LIKE와 CONCAT 인 것으로 보입니다. 주변에 다른 전쟁이 없다고 확신합니까? like, LIKE 문을 수행하기 전에 모든 주소 필드를 연결하지 않습니까?

업데이트 : tb_clients_phone_fax.client_id가 색인 생성되지 않은 것 같습니다. 색인 생성을하면 성능이 향상됩니다.

+0

내가 추가하기 전에 실제로 꽤 빨리 실행 : 난 그냥 CONCAT을 복용 시도하고 그것은 여전히 ​​매우 느리게 실행이 ... – mike

+0

tb_clients_phone_fax.client_id이 인덱싱되지 않습니다 tb_clients.client_id = tb_clients_phone_fax.client_id, 그것은 인덱스! – albertein

+0

ok, 나는 분명히 일을 다시 – mike

1

표 스키마를 보지 않고도 확실하게 말할 수는 없지만 모든 indicies에서 검색하지 않기 때문이라고 가정합니다.

전체 텍스트 검색에 대한 MySQL 매뉴얼을 확인하십시오. http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html 더 나은 답변을 얻으려면 스키마와 색인을 게시해야합니다.

1

tb_clients에는 client_id의 색인이 있고, tb_clients_phone_fax에는 client_id의 색인이 있어야합니다.

그런 다음 client-company, client-description, client-keywords에 대한 색인을 추가하십시오.

그러나, 나는 당신이 concuredated client_address,client_city,client_state,client_zip에서하고있는 비교를 위해 주요 속도 저하가 올 것이라고 내기를 원하기 때문에, concat없이이 비교를하는 다른 방법을 찾아보십시오. 연결된 항목의 데이터를 보유하는 테이블에 필드를 추가 한 다음 해당 필드를 비교할 수 있습니까? (추악한 내가 아는)

1

언급 한 색인 생성을 제외하고, 나의 첫 번째 생각은 귀하의 상황에 대해 전혀 알지 못합니다. 두 테이블에 몇 개의 행이 있습니까? 그들 중 하나는 단지 몇 천이고 다른 하나는 천만입니까? 쿼리 성능이 매우 큰 데이터 세트에 합류 한 것이 아니라고 가정하면 다음과 같습니다.

다른 사람들이 말했듯이 열의 색인이 생성되었는지 확인하십시오. 또한, 왜 fulltext 당신이 연결하는 열의 색인을 생성하고 두 번째 MATCH() AGAINST() 대신 CONCAT()와 같은 쿼리에서 사용합니까?

코드를 업데이트하여 우편 번호 패턴을 확인한 다음 이에 따라 쿼리를 작성하는 것은 어떻습니까? 또는 우편 번호 패턴이 아닌 경우 해당 열을 검색하는 것을 신경 쓰지 마십시오.

전체 (큰) 테이블을 검색해야하는 대용량 상황에서 잘 작동하는 한 가지 방법은 전체 테이블의 연결을 포함하는 열을 만드는 것입니다. 나는 그 칼럼에 fulltext 인덱스를 넣고 MATCH() AGAINST()를 사용하고 쿼리 시간이 매우 빨라요. 그래서 제 경험으로 풀 텍스트 인덱싱은 작업을 완료합니다.

이제 테이블 크기가 매우 크면 실시간 결합이 허용되지 않을 수 있습니다. 이 시점에서 몇 가지 옵션을 사용할 수 있지만 모두 최종 사용자 경험의 이점을 위해 백그라운드에서 합류하고 그 결과를 저장하는 변형입니다.

+0

글쎄, 실제로 두 테이블의 행 수가 같습니다. 30k와 같은 것 ... 우편 번호를 확인하는 것에 관한 전반적인 내용은 훌륭하지만 다른 국가의 고객에게는 매우 다른 우편 번호가 있습니다. \ - 색인의 내일을 확인하려고 계획 중입니다 ... – mike

0

연결된 정보가 포함될 '가짜'열이있는 tb_clients 테이블에 대한보기를 만들 것입니다.

또한 이전에 언급 한 id 열의 색인을 생성합니다.

는 당신은 내가 너무 일 오프에서 5 분입니다 테이블에 대한 뷰를 교체하고 (이 집계 컬럼으로 뷰에 의해 수행되고 있기 때문에)

을 CONCAT을 생략하고, 동일한 기본 쿼리를 사용합니다 I 많은 세부 사항에 들어갈 수 없습니다. 코드가 필요하다면 example sql 등은 나에게 알려주고 나중에 오늘 밤 또는 내일 당신을 위해 함께 넣을 것입니다.

0

한 아주 작은 팁 :

CONCAT(client_address,' ',client_city,', ',client_state,' ',client_zip) LIKE '%brooklyn%' 

전체 CONCAT가 필요합니까? 주 또는 우편 번호에 brooklyn이있는 많은 고객이 있습니까?

은 (또한,
는 foobar, MI 98765

의도적인가요이

1342 브루클린 거리 같은 주소와 일치 할 것을 깨닫게?)

+0

좋은 지적, 나도 몰랐습니다. 그것에 대해 생각해보십시오. – mike

1

첫 번째 단계를 천천히 디버깅 할 때 쿼리는 EXPLAIN SELECT ...을 실행하고 추측하는 대신 MySQL이 실제로 수행하는 작업을 살펴 ​​봅니다. 하지만 그렇습니다. tb_clients_phone_fax.client_id에 대한 색인이 다른 사람들처럼 도움이 될 것입니다.