Salam,
PHP və mysql ilə bir application-um var.
Server olaraq Digitalocean-dadir.
server parameterləri aşağıdakı kimidir.
1 GB RAM---1 CPU 25 GB SSD və 1000GB Transfer
Deməli mənim php codumun umumi strukturu belədir.
sql calisir bundan gelen melumatlar (təxminən 200 sətir)
loop içəriisndə bu məlumatlardan bəziləri ekrana verilir bəziləri parameter olaraq başqa funksiyalara oturulur bu funkisyalarda database-ə bağlanıb bəzi datanı çəkir və nəticəsini ekrana verir.
mənim bu 200 sətirlik məlumatı emal etməyim hardasa 2-3 dəqiqə çəkir.
Mənə belə gəlirki məlumatlar databasedən oxunduqca ekrana verilmir. Bütün hamsı bitdikdən sonra verilir.
bunu elə etmək olarmı ki, məlumatlar oxunduqca ekrana verilsin?
Verilmiş cavablar və yazılan şərhlər (6 cavab var)
1
Bəli, PHP backenddə işləyən dildir. Ona görə də belə də olmalıdır. Məlumatlar tam emal edib bitir, sonra hazır paket sizə göndərilir brauzerə.
Stream və ya bufer ilə etmək olar ki, bağlantı canlı qalsın, nəticələr axsın serverdən brauzerə.
Bufer məntiqi ilə edə bilərsiniz. Sadə bir nümunə yazım, kodunuzda nəzərə alarsınız:
Bu kodun nəticəsində 0, 1, 2, 3 .. və.s. ədədlər ekrana bir bir çıxır, hazır olduqca. sleep() isə sadəcə nümayiş etdirə bilmək üçündür, sizə lazım olmayacaq sleep. Sizə sadəcə bufer funksiyaları lazımdır.
0
Çox sağ olun Elvin bəy, təşəkkürlər. Yoxladım tam olaraq istədiyimiz kimi işlədi, sağ olun.
Bu arada bunu ümumi olaraq optimize etmək üçün nə etmək olar ki, script daha sürətli çalışsın?
0
Əgər işlətdiyiniz PHP 7.2-dirsə, memory limit mümkün qədər yuxarıdırsa (məsələn 512MB sınaya bilərsiniz, daha çoxunu etməyin, çünki cəmi 1GB resurs var deyə daha çoxu donduracaq sistemi. 512 belə çox olsa 368 yoxlamaq olar) deməli əsas şeylər OK-dur.
Sonra qalır əsas məsələ – kodun özünü optimizə etmək. Kodun nə olduğundan xəbərim yoxdur deyə bu haqda nəsə deyə bilmərəm. Bütün foreach loop-nu pastebin ilə filanla paylaşsanız, baxıb nəsə deyə bilərəm bəlkə.
0
Buyurun zəhmət olmasa baxıb fikirlərinizi bildirərdiniz.
https://pastebin.com/CiwecGGE
1
Bu kodda bir çox şey başqa class faylından gəlir deyə bilmək olmur nə dərəcədə qeyri optimallıq var loop-da.
Amma, çox güman ki, loop-un içində olan çoxsaylı $si_test_func obyekt metodları query-nı ağırlaşdıran əsas səbəbdir. Əsas loop query sadəcə iki table-a müraicət edir, table-lar da güman edirəm ki böyük deyil (Hər birində 100 minlərlə sətir yoxdur yəqin ki) – ona görə də loop özü çox sürətli işləməlidir. PHPMyAdmində filan yoxlaya bilərsiniz, yəqin 1-3 saniyə çəkər.
Loop-un içində isə çoxlu metodlar var ki, hər biri cari istifadəçinin parametrlərini gətirir.
Bu tip kodu bir çox yolla optimizə etmək olar.
Məsələn, 2 dənə sadəsini deyim:
1. Ana ideya – mysql query sayını kəskin azaltmaq. While loop-undan öncə userlərin datasını gətirən loop işlətmək və bütün userlərin parametrlərini ən qısa formada (bir bir funksiya ilə yox, kütləvi formada, birbaşa SQL-dən dartaraq) array-da saxlamaq.
Sonra da indiki əsas loop-un içində o array-ı userin İD-si ilə çağırmaq. Deyə bilərsiniz ki, bəs nə fərqi oldu? Fərqi o oldu ki, indiki halda hər sətir icra olunur və sonra yenidən çoxsaylı təkrar mysql query-lər icra olunur deyə hər sətir icrası təzədən 5-6 mysql query-nin nəticəsini gözləyərək hərəkət edir. Bu da hər kiçik mysql query (userin adını, ünvanını filan dartıb gətirən) 0.2-0.3 saniyə olarsa belə bir sətrin az qala 1 saniyəyə bitməsinə gətirib çıxaraq.
Bu da təxminən 200 saniyə deməkdir. Cəmdə də 200*4 – 800 mysql query icra edilmiş olur. Bir səhifədə 800 query dəhşətli bir şeydir və mütləq dəyişdirilməlidir.
Amma hər iki while-i ayri yazsanız, hər ikisi ağır query olsa belə query sayı düşəcək 800-dən 2-yə, və icra müddəti də olacaq 10-15 saniyə.
2. Ana ideya: Cron job ilə çalışaraq daimi şəkildə userdataları yeniləyib bir mysql table-da saxlayıb hər zaman istifadəyə hazır tutan script: Yox əgər userlərin datası bir table-da deyilsə (si_get_exam_evnt_dt_from_id, si_get_district_name və.s.) bir query ilə qayıtmırsa, mütləq bir neçə kombinasiya ilə hesablanırsa – o halda bu datanı hesablayıb hazır mysql table-da tutan bir cron job scripti yazsanız məsələ həll olar. Məsələn:
Cronjob-a qoyursunuz hər 10 dəqiqədən bir çalışır tutaq ki (interval asılıdır sizin user datasının – adının, levelinin, rayonunun və.s. nə dərəcədə tez-tez yenilənməsindən) və bu işi görür
– bütün lazımi querylər run olur və sonda başqa bir mysql table-da hamısı bir arada cəmlənir. Yəni sizə userin hansı datası lazımdırsa hamsı sütunlar şəklində o mysql table-da save edilir.
Sonra artıq indiki icra faylınızda obyekt metodları əvəzinə 1-ci dediyim metoddan istifadə edirsiniz, yəni əsas while-dan əvvəl bu userdata table-na bağlanıb userlərin datasını array-da saxlayırsınız, sonra while zamanı da obyekt metodlarını çalışdırmaqla yox, birbaşa array ilə display edirsiniz. – təkrar eidrəm, əgər dediyim 1ci metod işə yarayırsa, bu 2ciyə gərək yoxdur.
Vacib qeyd: bu dediklərimin heç biri optimal həll deyil, bundan qat-qat effektiv metodlar düşünmək olar data böyüdükcə. Araya digər toollar da qatmaq olar -Redis kimi şeylər. Və bütün prosesin icra vaxtını 1 saniyəyə belə salmaq olar. Sadəcə hazırki durumda məncə bu 2-sindən biri bəs edər sizin data ölçüsü üçün
0
Cox sağ olun Elvin bəy, bu şəkildə detallı yazdığınız üçün, Mənə elə gəlir birinci variantı tətibq edə bilərəm. Bu daha uyğun gəlir ilkin olaraq. Bütün tələbələrin məlumatlarını arraya yığıbç ikinci loopdan onları çağırmaq.
Bir daha çox sağ olun.
Sual verin
Cavab verin