2014-03-31 2 views
0

PHP 코드로 작성된 복잡한 쿼리를 기반으로 MySQL에서 데이터를 가져 오려고합니다. 데이터를 검색하는 속도가 너무 느립니다. 이 문제를 어떻게 해결할 수 있습니까? 성능을 향상시킬 방법이 있습니까? WAMP 서버를 사용하고 있습니다. PHP로 모든 작업을 수행해야합니다. 실제로 동일한 사용자의 모든 트윗을 연결하고 이름으로 배열에 넣고 싶습니다. 내가 twittersand이 같은 데이터 세트에서 동일한 사용자의 모든 트윗을 연결의 이름을 저장하는 $ 트위터 배열을 사용하고 있습니다 : 그것은 너무 무거운 수행하는 것입니다 왜MySQL에서 느린 데이터 검색

$number_of_twitters=sizeof($twitters); 

for($i=0;$i $number_of_twitters;$i++){ 
    $getTweetsQuery="SELECT Tweets FROM tweettable WHERE Name='$twitters[$i]'"; 
    $tweets=mysql_query($getTweetsQuery); 

$tweetString=""; 

while($tweetsRow=mysql_fetch_array($tweets)){ 
    $tweetString .= $tweetsRow[0]." "; 
} 

를?

+0

쿼리와 관련 코드 – Jacob

+0

...을 게시해야하며 저장 엔진 인 EXPLAIN 출력과 'show create table' 출력이 필요한 대부분을 제공합니다. 그것은 information_schema.tables의 rowsize 및 datalength와 함께 사용됩니다. – spencer7593

+0

감사합니다. spencer7593, – Arash

답변

3

응용 프로그램에서 발급 한 SQL을 캡처하십시오. 응용 프로그램에서 할 수 없다면 MySQL 일반 로그를 활성화 할 수 있지만 모든 세션의 모든 SQL 문을 기록합니다.

EXPLAIN을 사용하면 생성 된 액세스 플랜을 볼 수 있습니다.

knee-jerk 빠른 대답은 "인덱스 추가"이지만 키는 실행중인 쿼리에 대해 가장 적합한 인덱스를 결정하고 불필요한 인덱스를 제거합니다.

최적의 성능을 보장하지 못하는 조건부 쿼리가있을 수 있습니다. 예를 들어, 함수에서 열을 래핑하면 MySQL이 인덱스 범위 스캔과 인덱스 탐색을 수행 할 수 없습니다.

다른 무언가 빠른 대답은 실제 I/O를 줄이기 위해 더 많은 블록이 캐시되도록 인스턴스에 메모리를 추가하는 것입니다.

MyISAM 스토리지 엔진은 SELECT 문에 대해서조차도 테이블 수준 잠금을 취하고 동시성을 없애줍니다. InnoDB는 동시 질의로 훨씬 잘 수행된다.


UPDATE

이 쿼리에 가장 적합한 인덱스 :

... ON tweetable (Name, Tweets) 

현재 실행 계획을 보여줍니다 EXPLAIN :

SELECT Tweets FROM tweettable WHERE Name='$twitters[$i]' 

가 포함 인덱스 것 :

EXPLAIN SELECT Tweets FROM tweettable WHERE Name='foo' 

이상 적으로 설명 출력에 'Using index'가 표시되도록하는 것이 좋습니다. 그러나 적어도 MySQL은 인덱스를 통해 행에 액세스하기를 원하므로 테이블의 모든 행을 전체 스캔하여 행이 술어를 충족시키는 지 확인할 필요가 없습니다.

또한이 쿼리는 반복적 인 것으로 보입니다. 일반적으로 여러 문을 실행하는 대신 단일 문으로 행 집합을 검색하는 것이 더 효율적입니다. (그리고 이것은 각각의 실행이 매우 큰 테이블의 행 소수 당기는 및 조회 테이블의 전체 검사를 수행하는 경우에 특히이다.)

SELECT t.Tweets 
    FROM tweetable t 
WHERE t.Name = 'fee' 
    OR t.Name = 'fi' 
    OR t.Name = 'fo' 
    OR t.Name = 'fum' 
ORDER BY t.Name 

또는 당량

SELECT t.Tweets 
    FROM tweetable t 
WHERE t.Name IN ('fee','fi','fo','fum') 
ORDER BY t.Name 

MySQL에는 유용한 GROUP_CONCAT 함수가 있습니다.

SELECT GROUP_CONCAT(t.Tweets ORDER BY t.Name SEPARATOR ' ') AS tweetstring 
    FROM tweetable t 
WHERE t.Name IN ('fee','fi','fo','fum') 

참고 GROUP_CONCAT에 의해 반환 된 문자열의 길이는 group_concat_max_lenmax_allowed_packet 변수에 의해 제한됩니다.

+0

Thx, 매우 도움이되었지만 PHP로 모두해야합니다. 실제로 동일한 사용자의 모든 트윗을 연결하고 이름으로 배열에 넣고 싶습니다. – Arash