Foreach İle XML Okumanın Parçalanması ve Timeout Hatası
Merhabalar,
XML okuma yapıp veritabanına kayıt yaptığım bir kod dosyam mevcut.
Foreach döngüsü ile xml'deki tüm itemleri tek tek okumaktayım ve foreach döngüm şu şekilde;
foreach($xmlurl as $key => $xml){
// işlemler
}
bu şekilde tüm itemleri tek tek okuyup işlem yapıyorum ancak xml'deki item sayısı arttığından dolayı timeout hatası almaktayım. Test döngü sayısını alttaki gibi sınırladım.
foreach($xmlurl as $key => $xml){
$counter++;
if ($counter >= 1000) {
break;
}
// işlemler
}
Burada tespitim şudur; 1000 item okumaya kadar sorun yaşamıyorum ama 1200-1300 e çıkardığımda timeout hatası alıyorum. Hosting firması max_execution_time 'ı 3000 'e çıakrdı ancak çözüm olmadı.
Çözüm olarak şunu yapmak istiyorum. Foreach döngüsü ilk 1000 item'i okuduktan sonra tekrar kalan 1000 itemi okumasını bu sayede timeout 'u atlatacağımı düşünüyorum.
Bunu nasıl yapabilirim ya da farklı çözüm önerileriniz var ise aydınlatabilir misiniz ?
Aldığım Hata :
Request Timeout
This request takes too long to process, it is timed out by the server. If it should not be timed out, please contact administrator of this web site to increase 'Connection Timeout'.
Verdiğin cevaptan anladığım kadarıyla veritabanı tarafında optimizasyon sorunu yaşıyorsun.
Bunun çözümü şu şekilde olabilir.
Eğer sunucu taraflı bir çalışmaysa yapacağın işi böldürtebilirsin bu da şu şekilde olabilir.
<?php
$last_line_number = file_get_contents('last_line.txt') ?? 0;
for($x = $last_line_number; $x < count($xml); $x++) {
$data = $xml[$x];
// işlemler
$last_line_number++;
if($last_line_number % 1000 == 0){
file_put_contents('last_line.txt', $last_line_number);
break;
}
}
Ayrıca MySQL tarafı için de bir kaç tüyo verebilirim, INSERT işlemleri ne kadar fazla olursa olsun hızlı çalışacaktır fakat UPDATE sorguları aynı şekilde çalışmaz.
Optimize çalıştırmak istiyorsak
UPDATE table SET column = "new_data" WHERE column = 1 (YANLIŞ)
UPDATE table SET column = "new_data" WHERE column = 1 LIMIT 1 (DOĞRU)
Eklemiş olduğumuz LIMIT 1 ibaresi sadece 1 satırı güncelleyeceğini daha fazla derine inmemesini sağlar, ve böylece tek bir satırı güncelledikten sonra sorguyu sonlandırır.
Haricinde tekrar yapabileceğimiz tek bir şey daha var.
UPDATE table SET column = "new_data" WHERE column = 1 LIMIT 1
UPDATE table SET column = "new_data" WHERE column = 2 LIMIT 1
gibi tek tek sorguları atmaktansa 3 er 3 er şeklinde tek seferde de atabiliriz
UPDATE table SET column = "new_data" WHERE column = 1 LIMIT 1;
UPDATE table SET column = "new_data" WHERE column = 2 LIMIT 1;
UPDATE table SET column = "new_data" WHERE column = 3 LIMIT 1
Bu da bize her update attığımızda tek tek sorgu isteğinde bulunmadan tek seferde 3 sorguyu göndererek sıra sıra bu işlemleri yapması gerektiğini anlatmamızdır.
Tabi bu 3 ten fazla da olabilir ben sadece örnek verdim.
gibi