v2.5.2
Giriş yap

Foreach İle XML Okumanın Parçalanması ve Timeout Hatası

mcfearcombat
250 defa görüntülendi ve 1 kişi tarafından değerlendirildi

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'.

Cevap yaz
Cevaplar (4)
recepkaramanli61
303 gün önce

Çok verimli olmamakla beraber php flush() fonksiyonunu deneyebilirsin. https://www.php.net/manual/en/function.flush.php
Veya belirli bir item'i database aktardıktan sonra devam edeceği satırı url'e parametre olarak verip sayfayı yönlendirirsin, bu şekilde her seferinde sunucudaki 90 sn işlem limitini sıfırlamış olursun. aynı şekilde database de de işlem limitine takılırsan her döngüdeki işlem sayısını azaltarak devam edebilirsin.

database
305 gün önce

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

emmir2
345 gün önce

XMLReader kullanmayı denedin mi ?

mcfearcombat
352 gün önce

Yaptığı testlerde xml 'i okumanın timeout hatasına sebep vermediği veritabanı kayıt işlemlerinin buna neden olduğunu tespit ettim. XML 'den verilerin okunması 1 saniyenin altında sürüyor ancak veritabanına kayıt uzun sürüyor.

bunu aşabilmek için transaksiyon fonksyionu kullanarak güncellemeleri toplu yaptım ancak genede çözüm olmadı.