I'm looping through 40 associative arrays:
array(
'key0' => value,
'url0' => value,
'tit0' => value,
'cdn0' => value,
'cdn1' => value,
'cdn2' => value,
)
and I am performing multiple select
and one possible insert
queries. I tried to optimize the performance by reducing the amount of queries.
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;
}
This is however slow (the loop takes about 4.2 seconds). I tried making it faster by removing a query.
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;
}
This for some reason made it even slower (5-6s). Thus, I'm left clueless. How can I make this have a reasonable load time? I tried putting $sth2->execute
in the if(!$ret...)
statement but that doesn't give me any speed gain either.
It doesn't seem to be the INSERT
that is the problem due to most of the array
data being already IN
the database. Whenever I run queries in phpmyAdmin it does it in 0.0000000003 seconds so it must have something to do with the loop.
Speedup #1: Move $sth2->execute();
to right after the first if
. You don't seem to need the result if the url
test succeeds.
Speedup #2: Be sure to have INDEX(url)
and INDEX(key)
;
Speedup #3: Change INDEX(key)
to UNIQUE(key)
and skip the SELECT ... key
; simply check for dup key after doing the INSERT
.
Speedup #4: (This one may or may not help.) Do all of the SELECT ... url
in a single query: SELECT ... url IN (40-urls-in-list)
. (Requires Speedup #2.) Save the results in an associative array and walk through it to do the rest of your SELECT/INSERT stuff.
Speedup #5: Build a 'batch' INSERT
(multiple rows in a single INSERT
), then execute
it at the end of the 40-item loop.
Please provide SHOW CREATE TABLE
.
MyISAM? or InnoDB? Have you tuned innodb_buffer_pool_size to be about 70% of available RAM? If not, this might improve performance.
Is what you considered that possibility? https://dev.mysql.com/doc/refman/5.0/en/insert-select.html
Unfortunately, there is not enough information about your MySQL indexing strategy or amount of information you select.
Possible issues that come to my mind in first second:
Solution to all those would be to echo a lot of debug data with precision timestamp, read them over and log SQL queries to MySQL server log and run all these in one batch in console/PHPMyAdmin for better debugging.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.