2009-04-09 34 views
10

Ben genellikle büyük diziler, yoksa işlemek için MySQL sorguları çalıştırmak için gereken PHP dinamik büyük miktarda veri var.Bir PHP döngüsünde MySQL sorgusu koymak kötü mü?

INSERT-ed edilecek veya GÜNCELLEME-ed bilgisi döngü olmadan INSERT veya UPDATE gibi birçok süreçleri çalıştırmak için daha iyi bir yolu var mı?

Örnek (I kısalık uğruna hazırlanmış deyimi kullanmıyordu): Aslında tek seferde birden fazla sorgulama yapabilirsiniz 1

 
$myArray = array('apple','orange','grape'); 

foreach($myArray as $arrayFruit) { 
$query = "INSERT INTO `Fruits` (`FruitName`) VALUES ('" . $arrayFruit . "')"; 
mysql_query($query, $connection); 
} 
+0

iyi bir soru;) – markus

+0

haha ​​... ben gerçekten merak ediyordum ve ben istemedim üzgün bir pislik hounding gibi potansiyel olarak 100 insert ifadeleri birlikte (eğer – johnnietheblack

cevap

20

SEÇENEĞİ.

$queries = ''; 

foreach(){ 
    $queries .= "INSERT....;"; //notice the semi colon 
} 

mysql_query($queries, $connection); 

Bu işleminiz üzerinde tasarruf sağlar.

SEÇENEK 2

ekinizin aynı tablo için basit, sorgu aşağıdaki gibi görünen biter BİR sorgusu

$fruits = "('".implode("'), ('", $fruitsArray)."')"; 
mysql_query("INSERT INTO Fruits (Fruit) VALUES $fruits", $connection); 

yılında, çok sayıda ekleme yapabilirsiniz ise:

$query = "INSERT INTO Fruits (Fruit) 
    VALUES 
    ('Apple'), 
    ('Pear'), 
    ('Banana')"; 

Bu muhtemelen gitmek istediğiniz yoludur.

+0

doğru ... öylesine büyük bir yükü bakmak) üzerinden ayrı. mantıklı ... teşekkürler :) – johnnietheblack

+1

Seçenek # 2 gerçekten sallanabiliyorsanız gitmenin en iyi yolu. – jerebear

+0

haha ​​bu biraz merak uyandırıcı ... zeki. teşekkürler – johnnietheblack

5

Eğer mysqli sınıfını varsa, hazırlanmış deyimi kullanarak eklemek için değerler adımlayabilirsiniz. Orijinal jerebear bölünmesi yöntemi üzerinde solüsyon (Daha önce kullanmış ve aşk) ilgili dikkate alınması gereken

$sth = $dbh->prepare("INSERT INTO Fruits (Fruit) VALUES (?)"); 
foreach($fruits as $fruit) 
{ 
    $sth->reset(); // make sure we are fresh from the previous iteration 
    $sth->bind_param('s', $fruit); // bind one or more variables to the query 
    $sth->execute(); // execute the query 
} 
3

bir şey daha kolay okunmasını sağlayacak olmasıdır. Patlama, işlemci döngülerinden daha pahalı olabilecek, daha fazla programcı beyin döngüsünü anlamaya çalışır. erken optimizasyon, blah, blah, blah ... :)

+0

iyi bir noktaya dikkat edin ... beynim – johnnietheblack

+0

olduğu gibi şifreleniyor Elbette, tüm patlamayı ve diğer çirkin bitleri gizleyebilirsiniz. okumayı kolaylaştırmak ve fayda elde etmek için bir işlev veya sınıf. – Zoredache

+1

Fonksiyonun öngörülebilir ve anlaşılabilir bir şey yapması gerektiğini, orijinal php döngüsünün okunması çok kolay olduğunu ve performans açısından kazanılacak fazla bir şey olmadığına bahse girerim. 'Akıllı' çözümleri sevdiğimden, bu konuda bir şeytan avukatı olduğumu kabul etmeliyim. –

0

Jerebear'ın şu anki projelerimden biri için ikinci seçeneği gibi bir şey inşa etme cevabından ilham aldım. Kaydın kesme hacminden dolayı, tüm verileri bir kerede kaydedemedim ve yapamadım. Bu yüzden ithalat yapmak için this'u oluşturdum. Verilerinizi eklersiniz ve her kayıt bittiğinde bir yöntem çağırırsınız. Belli, yapılandırılabilir bir kayıt sayısından sonra, bellekteki veriler jerebear'ın ikinci seçeneği gibi bir kütle ekiyle kaydedilir. En DBMS büyüklüğüne bir üst sınır var çünkü

Bu verilerin gerçekten büyük miktarlarda oldukça tehlikeli olabilir: Bir INSERT birden DEĞER-bloklarla jerebear cevabı konusunda dikkat edilmesi gereken

// CREATE TABLE example (Id INT, Field1 INT, Field2 INT, Field3 INT); 
$import=new DataImport($dbh, 'example', 'Id, Field1, Field2, Field3'); 
foreach ($whatever as $row) { 
    // add data in the order of your column definition 
    $import->addValue($Id); 
    $import->addValue($Field1); 
    $import->addValue($Field2); 
    $import->addValue($Field3); 
    $import->nextRow(); 
} 
$import->lastRow(); 
2

Bir şey işleyebileceği komutlar. Bunu çok fazla VALUE bloğu aşarsanız, ekiniz başarısız olur. MySQL'de örneğin limit genellikle 1 MB AFAIK'dir.

Bu nedenle, en büyük boyutun ne olduğunu belirlemelisiniz (ideal olarak çalışma zamanında, veritabanı meta verilerinden alınabilir) ve değer listelerinizi birkaç INSERT üzerinde yayıp geçmediğinizden emin olmalısınız.

+0

Bu durumda limit atlamaktan kaçınmak için array_chunk ve loop kombinasyonunu uygulamak akıllıca olacaktır. – jerebear

0
foreach ($userList as $user) { 
$query = 'INSERT INTO users (first_name,last_name) VALUES("'.$user['first_name'].'",  "' . $user['last_name'] . '")'; 
mysql_query($query); 

} Yukarıdaki bir döngü kullanarak aşağıdaki .Instead deneyin kullanma

Insted, tek bir veritabanı sorguya veri birleştirebilirsiniz.

$userData = array(); 
foreach ($userList as $user) { 
$userData[] = '("' . $user['first_name'] . '", "' . $user['last_name'] . '")'; 
} 
$query = 'INSERT INTO users (first_name,last_name) VALUES' . implode(',', $userData); 
mysql_query($query); 

Produces: 

INSERT INTO users (first_name,last_name) VALUES("John", "Doe"),("Jane", "Doe")...