PHP / SQL - - Bu kodu hızlandırmak Kısa Kod ama şu anda inanılmaz uzun sürer

4 Cevap php

Doğru, bu kod oldukça büyük boyutlu bir dizi (yaklaşık 28.000 satır ve 16 bölümden oluşur) geçer.

Olayların Sipariş:

  1. Veri veritabanında olup olmadığını kontrol edin
  2. Varsa - yeni veriyle güncelleyin
  3. o yoksa - onu takın

Basit.

Ama şu anda bence o 30 dakika devraldı bu geçmesi ve Still gidiyor.

$counter = 0;
$events = sizeof($feed_array['1'])-1;
while($counter <= $events ) {

	$num_rows = mysql_num_rows(mysql_query("SELECT * FROM it_raw WHERE perfID = '".addslashes($feed_array['16'][$counter])."'")); 
	if($num_rows) {
		$eventDate=explode("/", $feed_array['1'][$counter]); //print_r($eventDate);
		$eventTime=explode(":", $feed_array['2'][$counter]); //print_r($eventTime);		
		$eventUnixTime=mktime($eventTime[0], $eventTime[1], "00", $eventDate[1], $eventDate[0], $eventDate[2]);

		mysql_query("UPDATE `it_raw` SET  
					`eventtime` =  		'".$eventUnixTime."',
					`eventname` =  		'".addslashes($feed_array['3'][$counter])."',
					`venuename` =  		'".addslashes($feed_array['4'][$counter])."',
					`venueregion` =  	'".addslashes($feed_array['5'][$counter])."',
					`venuepostcode` =  	'".addslashes($feed_array['6'][$counter])."',
					`country` =  		'".addslashes($feed_array['7'][$counter])."',
					`minprice` =  		'".addslashes($feed_array['8'][$counter])."',
					`available` =  		'".addslashes($feed_array['9'][$counter])."',
					`link` =  			'".addslashes($feed_array['10'][$counter])."',
					`eventtype` =  		'".addslashes($feed_array['11'][$counter])."',
					`seaOnSaleDate` =   '".addslashes($feed_array['12'][$counter])."',
					`perOnSaleDate` =   '".addslashes($feed_array['13'][$counter])."',
					`soldOut` =  		'".addslashes($feed_array['14'][$counter])."',
					`eventImageURL` =   '".addslashes($feed_array['15'][$counter])."',
					`perfID`=  			'".addslashes($feed_array['16'][$counter])."'
					WHERE  `perfID` = ".$feed_array['16'][$counter]." LIMIT 1 ;");
		echo "UPDATE ".$feed_array['16'][$counter].": ".addslashes($feed_array['3'][$counter])."\n";
	} else {
		$eventDate=explode("/", $feed_array['1'][$counter]); //print_r($eventDate);
		$eventTime=explode(":", $feed_array['2'][$counter]); //print_r($eventTime);		
		$eventUnixTime=mktime($eventTime[0], $eventTime[1], "00", $eventDate[1], $eventDate[0], $eventDate[2]);
		$sql = "INSERT INTO  `dante_tickets`.`it_raw` (
				`id` ,
				`eventtime` ,
				`eventname` ,
				`venuename` ,
				`venueregion` ,
				`venuepostcode` ,
				`country` ,
				`minprice` ,
				`available` ,
				`link` ,
				`eventtype` ,
				`seaOnSaleDate` ,
				`perOnSaleDate` ,
				`soldOut` ,
				`eventImageURL` ,
				`perfID`
				)
				VALUES (
					NULL ,  
					'".$eventUnixTime."',  
					'".addslashes($feed_array['3'][$counter])."',  
					'".addslashes($feed_array['4'][$counter])."',  
					'".addslashes($feed_array['5'][$counter])."',  
					'".addslashes($feed_array['6'][$counter])."',  
					'".addslashes($feed_array['7'][$counter])."',  
					'".addslashes($feed_array['8'][$counter])."',  
					'".addslashes($feed_array['9'][$counter])."',  
					'".addslashes($feed_array['10'][$counter])."',  
					'".addslashes($feed_array['11'][$counter])."',  
					'".addslashes($feed_array['12'][$counter])."',  
					'".addslashes($feed_array['13'][$counter])."',  
					'".addslashes($feed_array['14'][$counter])."',  
					'".addslashes($feed_array['15'][$counter])."',  
					'".addslashes($feed_array['16'][$counter])."'
				);";

		mysql_query($sql) or die(mysql_error().":".$sql);
		echo "Inserted ".$feed_array['16'][$counter].": ".addslashes($feed_array['3'][$counter])."\n";
	}
	unset($sql);
	$counter++; 	
}

UPDATE

Ben sadece bir satır bir profil yürütülen:

mysql> EXPLAIN SELECT * FROM it_raw WHERE perfID = 210968;
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------+
| id | select_type | table  | type | possible_keys | key    | key_len | ref   | rows | Extra |
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------+
|  1 | SIMPLE      | it_raw | ref  | perfID        | perfID | 4       | const |    1 |       | 
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------+
1 row in set (0.07 sec)

UPDATE 2

Bir kopyasını kontrol etmek - - o eylemi [insert veya depolayan deneyin ve bunun yerine hemen UPDATE ve INSERT deyimleri yürüten "hız" şeyleri, için, ben şimdi ilk seçme çalışır yani sadece (bir değişken bunları koydum update]). Döngünün sonunda tüm statments çalıştırır.

Şimdi dışında, sözdizimi yanlış olduğunu MySQL hata ile geliyor. (Zaman başlangıçta yanlış bir şey yoktu).

Ben sadece birlikte mysql_query yerini ettik:

. $ Sql_exec = "SELECT ....;";

Ben biçimlendirme için burada eksik bir şey var mı?

UPDATE 3 OK finally fixed it Lessons Learned:

  1. Veritabanında ilk mantık arama yapın
  2. Toplu insert / güncellemeleri yürütmek.

İşte şimdi (30 dk + yerinden) çalıştırmak için yaklaşık 60 saniye sürer nihai kodudur

while($counter <= $events ) {

    	$num_rows = mysql_num_rows(mysql_query("SELECT * FROM it_raw WHERE perfID = '".addslashes($feed_array['16'][$counter])."'")); 
    	if($num_rows) {
    		$eventDate=explode("/", $feed_array['1'][$counter]); //print_r($eventDate);
    		$eventTime=explode(":", $feed_array['2'][$counter]); //print_r($eventTime);		
    		$eventUnixTime=mktime($eventTime[0], $eventTime[1], "00", $eventDate[1], $eventDate[0], $eventDate[2]);

    		$sql_exec[] =	"UPDATE `it_raw` SET `eventtime` = '".$eventUnixTime."',`eventname` = '".addslashes($feed_array['3'][$counter])."',`venuename` = '".addslashes($feed_array['4'][$counter])."',`venueregion` = '".addslashes($feed_array['5'][$counter])."',`venuepostcode` = '".addslashes($feed_array['6'][$counter])."',`country` = '".addslashes($feed_array['7'][$counter])."',`minprice` = '".addslashes($feed_array['8'][$counter])."',`available` = '".addslashes($feed_array['9'][$counter])."',`link` = '".addslashes($feed_array['10'][$counter])."',`eventtype` = '".addslashes($feed_array['11'][$counter])."',`seaOnSaleDate` = '".addslashes($feed_array['12'][$counter])."',`perOnSaleDate` = '".addslashes($feed_array['13'][$counter])."',`soldOut` =  '".addslashes($feed_array['14'][$counter])."',`eventImageURL` =   '".addslashes($feed_array['15'][$counter])."',`perfID`='".addslashes($feed_array['16'][$counter])."' WHERE `perfID` = ".$feed_array['16'][$counter]." LIMIT 1;";
    		echo "UPDATE ".$feed_array['16'][$counter].": ".addslashes($feed_array['3'][$counter])."\n";
    	} else {
    		$eventDate=explode("/", $feed_array['1'][$counter]); //print_r($eventDate);
    		$eventTime=explode(":", $feed_array['2'][$counter]); //print_r($eventTime);		
    		$eventUnixTime=mktime($eventTime[0], $eventTime[1], "00", $eventDate[1], $eventDate[0], $eventDate[2]);
    		$sql_exec[] = "INSERT INTO  `it_raw` (`id` ,`eventtime` ,`eventname` ,`venuename` ,`venueregion` ,`venuepostcode` ,`country` ,`minprice` ,`available` ,`link` ,`eventtype` ,`seaOnSaleDate` ,
    				`perOnSaleDate` ,`soldOut` ,`eventImageURL` ,`perfID`) VALUES ( NULL ,'".$eventUnixTime."','".addslashes($feed_array['3'][$counter])."','".addslashes($feed_array['4'][$counter])."','".addslashes($feed_array['5'][$counter])."','".addslashes($feed_array['6'][$counter])."','".addslashes($feed_array['7'][$counter])."','".addslashes($feed_array['8'][$counter])."','".addslashes($feed_array['9'][$counter])."','".addslashes($feed_array['10'][$counter])."','".addslashes($feed_array['11'][$counter])."','".addslashes($feed_array['12'][$counter])."','".addslashes($feed_array['13'][$counter])."','".addslashes($feed_array['14'][$counter])."','".addslashes($feed_array['15'][$counter])."','".addslashes($feed_array['16'][$counter])."');";

    		//mysql_query($sql) or die(mysql_error().":".$sql);
    		echo "Inserted ".$feed_array['16'][$counter].": ".addslashes($feed_array['3'][$counter])."\n";
    	}
    	unset($sql);
    	$counter++; 	
    }

    foreach($sql_exec as $value) {
    	mysql_query($value) or die (mysql_error().": ".$value);	
    }

4 Cevap

Sen kod az sorguları çalışır böylece gruba ekler ve güncelleştirmeler gruplama deneyebilirsiniz.

Örneğin, yaparsın grup eklerin tüm bir çok büyük insert içine, ya da belki grup her 100 ekler.

Ayrıca gradbot önerilen olarak hazırlanmış deyimleri kullanarak yardımcı olabilir.

Bunun dışında, bunun bir parçası yavaşlığından büyük katkı olduğunu söylemek çok kolay değil. Bunu belirlemek için bir profilcisini kullanmak gerekir, daha küçük bir veri kümesi kullanılarak nedenle örneğin profilli komut makul bir süre çalışır.

Sen şeylerin bir dizi yapabilirsiniz.

Bu deneyin. Ben bunu test etmek mümkün değilim ama sözdizimi doğru olmalıdır.

$counter = 0;
$events = sizeof($feed_array['1']) - 1;
while($counter <= $events )
{
  $eventDate = explode("/", $feed_array['1'][$counter]); //print_r($eventDate);
  $eventTime = explode(":", $feed_array['2'][$counter]); //print_r($eventTime);             
  $eventUnixTime = mktime($eventTime[0], $eventTime[1], "00", $eventDate[1], $eventDate[0], $eventDate[2]);

  $data = array(
    'eventtime'     => $eventUnixTime,
    'eventname'     => addslashes($feed_array['3'][$counter]),
    'venuename'     => addslashes($feed_array['4'][$counter]),
    'venueregion'   => addslashes($feed_array['5'][$counter]),
    'venuepostcode' => addslashes($feed_array['6'][$counter]),
    'country'       => addslashes($feed_array['7'][$counter]),
    'minprice'      => addslashes($feed_array['8'][$counter]),
    'available'     => addslashes($feed_array['9'][$counter]),
    'link'          => addslashes($feed_array['10'][$counter]),
    'eventtype'     => addslashes($feed_array['11'][$counter]),
    'seaOnSaleDate' => addslashes($feed_array['12'][$counter]),
    'perOnSaleDate' => addslashes($feed_array['13'][$counter]),
    'soldOut'       => addslashes($feed_array['14'][$counter]),
    'eventImageURL' => addslashes($feed_array['15'][$counter]),
    'perfID'        => addslashes($feed_array['16'][$counter]),
  );

  $update = array();
  foreach ($data as $key => $value)
    $update[] = "`$key` = '$value'";

  $sql = "INSERT INTO `dante_tickets`.`it_raw`" .
    '(`id`, `'. implode ('`,`', array_keys($data)) . '`) VALUES ' .
    '(NULL, ' . implode (',', $data) . ') ON DUPLICATE KEY UPDATE ' . 
    implode (',', $update);

  mysql_query($sql) or die(mysql_error().":".$sql);
  echo "Inserted or Updated".$feed_array['16'][$counter].": ".addslashes($feed_array['3'][$counter])."\n";

  unset($sql);
  $counter++;     
}

Ben bu perfID benzersiz bir anahtar gerektirir söylemeyi unutmuşum.

  1. Bu sorguyu profilli var?

    '([[$ Sayaç] $ feed_array '16]). Addslashes "it_raw WHERE perfID =" SELECT *'. '""

    GERÇEKTEN hızlı olmadığı sürece yani .. bunu 28000 kez çalıştırmak, çünkü bir baş ağrısı neden olur. EXPLAIN syntax kullanın ve gerekirse uygun bir dizin ekleyin.

    EDIT: profili ile, ben size EXPLAIN kullanmayı denemelisiniz anlamına mysql istemi MySQL Query Optimizer bu sorgu için ne öneriyor yürütme planı görmek için. Yani, istemi üzerine, çalıştırın:

    EXPLAIN SELECT * FROM it_raw WHERE perfID = 426; 
    # Change this id to something existing and valid
    

    Ne görmek istediğiniz bir dizini kullanarak, ve SADECE bir dizin olmasıdır. Eğer çıkışını anlamak yoksa, kopyalama ve bu yüzden seninle bu gidebilirsiniz buraya yapıştırın.

    UPDATE: Bu kabaca 28000 * 0.07 = 1960 saniye, ya Gördüğünüz gibi, bu veri dizisinde her satır için 0.07 saniye sürer, artı aslında veritabanını sorgulamak için zaman, vb sonucu aktarmak veri var ya değilse 32 dakika, sadece kontrol etmek. Sen veriler zaten varsa kontrol başka yolu ile gelmek gerekiyor ... Bir çok basit optimizasyon olabilir:

    EXPLAIN SELECT perfId FROM it_raw WHERE perfID = 210968;
    

    Bu şekilde, perfId üzerinde dizin kullanabilirsiniz ve tablo ziyaret gerekmez

  2. Mümkünse, döngü içinde her çalıştırmak için veritabanını quering önlemek için deneyin. Belki de PHP hafızasına uyacak kimlikleri büyük bir diziye veritabanından kimlikleri almak mümkün mü? Bu senin için büyük veri dizisinde her satır için veritabanını quering daha çok daha hızlı olacaktır.

Bu prepared statements yapıldığı için tam bir senaryo:

$prepared_statement =
    $DB->prepare('INSERT INTO table(column, column) VALUES(?, ?)');
loop {
    $prepared_statement->execute(array('value1', 'value2');
}

Bu MySQLi ve PDO sarma uygulanacağı. Sadece sorgu kez ve automagically zaman (gelişimsel ve executional hem de) ve baş ağrısı tasarruf, verilen verileri sanitizes derler.