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
) 。execute
40개 항목 루프의 끝에 있습니다.
제공해주세요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
'programing' 카테고리의 다른 글
JavaScript와 의 JavaScript (0) | 2022.09.27 |
---|---|
Android "gps requires ACCESS_FINE_LOCATION" 오류(내 매니페스트 파일에 이 오류가 포함됨) (0) | 2022.09.26 |
numpy 배열이 비어 있는지 확인하려면 어떻게 해야 합니까? (0) | 2022.09.26 |
execute()를 사용한 여러 SQL 문의 실행 (0) | 2022.09.26 |
잘못된 후크 호출입니다.후크는 기능 구성 요소의 본체 내부에서만 호출할 수 있습니다. (0) | 2022.09.26 |