programing

PHP 루프 - SQL 성능 저하

bestcode 2022. 9. 26. 23:07
반응형

PHP 루프 - SQL 성능 저하

40개의 어소시에이트 어레이를 루프하고 있습니다.

array(
  'key0' => value,
  'url0' => value,
  'tit0' => value,
  'cdn0' => value,
  'cdn1' => value,
  'cdn2' => value,
)

그리고 나는 여러 가지 공연을 하고 있다.select그리고 하나 가능한 한 가지 insert문의합니다.쿼리 양을 줄여 성능을 최적화하려고 했습니다.

foreach($buf){
  $sth1->execute();//SELECT * FROM metadata WHERE url = '{$buf['url0']}'
  $sth2->execute();//SELECT * FROM metadata WHERE key = '{$buf['key0']}'

  if(!$ret=$sth1->fetch(PDO::FETCH_ASSOC)){
    if($sth2->fetch(PDO::FETCH_ASSOC)){
      die( 'key duplicate - error' );
    }

    $data[ ] = $buf;

    $sth3->execute();//INSERT INTO metadata ...
  } else {
    $data[ ] = $ret; 
}

단, 이 동작은 느립니다(루프에는 약 4.2초 걸립니다).쿼리를 삭제하여 더 빠르게 하려고 했습니다.

foreach($buf){
  $sth1->execute();//SELECT * FROM metadata WHERE url = '{$buf['url0']}' OR key = '{$buf['key0']}'

  if(!$ret=$sth1->fetch(PDO::FETCH_ASSOC)){       
    $sth3->execute();//INSERT INTO metadata ...

    $data[ ] = $buf;
  } else {
    if($ret['key']==$generated_key){die('key duplicate - error');}

    $data[ ] = $ret; 
}

어떤 이유로 인해 속도가 더 느려졌습니다(5-6초).그래서, 나는 아무것도 모르는 채로 남겨졌다.어떻게 하면 적절한 로드 시간을 가질 수 있을까요?퍼팅을 해봤는데$sth2->execute에서if(!$ret...)그렇다고 해서 속도가 빨라지는 것도 아닙니다.

그건 아닌 것 같아INSERT그것이 대부분의 이유로 인한 문제입니다.array데이터가 이미 사용되고 있다IN데이터베이스입니다.phpmyAdmin에서 쿼리를 실행할 때마다 0.0000000003초 만에 실행되므로 루프와 관련이 있을 것입니다.

스피드업 No.1: 이동$sth2->execute();첫 번째 직후에if결과가 필요없을 것 같은데url테스트는 성공했습니다.

스피드업 #2: 반드시INDEX(url)그리고.INDEX(key);

속도 향상 3: 변경INDEX(key)로.UNIQUE(key)를 생략합니다.SELECT ... key; 를 실행한 후 dup 키를 체크하기만 하면 됩니다.INSERT.

스피드업 #4: (이것이 도움이 될 수도 있고 안 될 수도 있습니다.)모든 작업을 수행합니다.SELECT ... url단일 쿼리에서 다음을 수행합니다.SELECT ... url IN (40-urls-in-list)(Speedup #2가 필요합니다.) 결과를 연관지을 수 있는 어레이에 저장하고 그 어레이를 통해 SELECT/INSERT 작업을 수행합니다.

스피드업 #5: '배치' 구축INSERT(단일 행에 추가) INSERT) 。execute40개 항목 루프의 끝에 있습니다.

제공해주세요SHOW CREATE TABLE.

MyISAM? InnoDB?innodb_buffer_pool_size를 사용 가능한 RAM의 약 70%로 조정했습니까?그렇지 않으면 성능이 향상될 수 있습니다.

그런 가능성이 있다고 생각했나?https://dev.mysql.com/doc/refman/5.0/en/insert-select.html

안타깝게도 MySQL 인덱싱 전략 또는 선택한 정보 양에 대한 정보가 부족합니다.

첫 번째 순간에 생각나는 문제:

  • MySQL에서 쿼리를 수행할 때 쿼리 캐시를 누르면 루프 캐시에서 만료됩니다.
  • 데이터베이스의 빈약한 색인화 전략 - varchar에 의한 선택이 항상 최선의 해결책은 아니며 char(16)와 MD5 sum(또는 유사한 것)을 사용하는 것이 아마도 조금 더 나은 접근법일 것이다.
  • 반복에 눈에 띄지 않는 루프가 있습니다.

이 모든 문제를 해결하려면 많은 디버깅 데이터를 정확한 타임스탬프로 에코하고, 이를 읽고 SQL 쿼리를 MySQL 서버 로그에 기록하여 콘솔/PHPyAdmin에서 이 모든 것을 일괄적으로 실행하여 디버깅을 개선해야 합니다.

언급URL : https://stackoverflow.com/questions/30138264/php-loop-poor-sql-performance

반응형