Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Post SQL

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
Commandx
Üye
Mesajlar: 143
Kayıt: 01 Oca 2008 05:34

Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Post SQL

Mesaj gönderen Commandx » 21 Eyl 2019 03:28

Arkadaşlar, Uzak Bir Firebird 2.5 Sunucum var, Datalarım Ordaki Sunucumda Saklı
Havuz Adında her ay boşalttığım bir Tablom var
Clientler, her ay oluşturdukları verileri normalde Row Row yani satır satır olarak Döngüyle gönderiyorlar, yani bir satırlık verinin Havuz dediğim Tabloya kaydedilmesi bağlantı hızına göre yaklaşık 20-40 ortalama 30 saniye sürüyor Hal böyleyken 600 kayıt = 600*30 = 18.000 saniye eder.
18.000 saniye = 300 dakika = 5 saat ediyor.
Verileri 5 saat bekleyip 1 Row data dahi eksik gelmeden işlem yapmamam gerekiyor. yani Tüm Clientlerdeki Dataların Tamamen Havuz Tablosuna girmiş olması gerek.
Verileri Döngüye bağlı Row Row değil de
Queryden Filtre edilmiş haliyle Tek atımda Post edebilme imaknı var mı, Örnek bulamadım da :(=

Kullandığım Kod

Kod: Tümünü seç

for i:=0 to UniQuARSIV.RecordCount-1 do begin
try
ProgressBar.Position:=UniQuARSIV.RecNo;
UniQuMERKEZARSIV.Insert;
UniQuMERKEZARSIV.FieldByName('TCKIMLIK').Value:=UniQuARSIV.FieldByName('TCKIMLIK').Value;
UniQuMERKEZARSIV.FieldByName('ADSOYAD').Value:=UniQuARSIV.FieldByName('ADSOYAD').Value;
UniQuMERKEZARSIV.FieldByName('YIL').Value:=UniQuARSIV.FieldByName('YIL').Value;
UniQuMERKEZARSIV.FieldByName('AY').Value:=UniQuARSIV.FieldByName('AY').Value;
.
. // Buralarda 60 Adet Alan bulunuyor  
.
UniQuMERKEZARSIV.FieldByName('BIRIMI').Value:=UniQuARSIV.FieldByName('BIRIMI').Value;
UniQuMERKEZARSIV.FieldByName('ISLENDIMEDI').Value:=UniQuARSIV.FieldByName('ISLENDIMEDI').Value;
UniQuMERKEZARSIV.FieldByName('UNIQUEALANX').Value:=UniQuARSIV.FieldByName('UNIQUEALAN').Value;
UniQuMERKEZARSIV.Post;
UniQuARSIV.Next;
except


Bu veriler gelinceye kadar 5 saat PC açık kalmak zorunda , Yarım gün iş yapamaz oluyorum
Acaba bunun kısa bir yolu yok mu?
Clientlerde içinde bulunulan Aya göre filtre edilmiş verilerin (Yaklaşık 10 ila 200 adet kayıt) Başka bir metotla Post Edilebilir mi
Döngü ile her bir ROW kaydı bayağı zaman alıyor.

Bunun SQL kodu var mı , varsada bayağı araştırdım bulamadım Eski usül For döngüsüyle yada EOF oluşuncaya kadar kaydediyorum bu da çok yavaş.

EDİT : Kodlarımda Küçük bir hata buldum, düzelttim Bir satır row un gelmesi 15 saniyeye düştü ama yinede zaman yetersiz.
En son Commandx tarafından 23 Eyl 2019 08:16 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
http://www.delphibasics.co.uk/RTL.asp?Name=DaysBetween
Zamane tickcount'u
except
ON E: Exception do
Begin
Application.MessageBox(Pchar('Can sıkıntısı '+#13+E.Message),'Hata',MBOKk+MB_ICONWARNING);
Abort;
End;
end;

Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2151
Kayıt: 12 Haz 2003 03:05
Konum: merkez camii yanı

Re: Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Sort SQL

Mesaj gönderen freeman35 » 21 Eyl 2019 04:09

http://www.winton.org.uk/zebedee/
bu yada benzerlerini bir incele. Bağlatıyı sıkıştırma opsiyonu da var.
filtre dediğin "where", sıralama, yani senin sort dediğinde bunlar en temel sql komutları. sort, where clause dan dönen result uygulanır.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!

ertank
Üye
Mesajlar: 1238
Kayıt: 11 Eyl 2015 11:45

Re: Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Sort SQL

Mesaj gönderen ertank » 22 Eyl 2019 04:54

Merhaba,

UniDAC bileşenleri kullanıyor olmanıza istinaden aşağıdaki örneğe benzer şekilde kodunuzu güncelleyip tek seferde tüm veriyi kayıt etmeyi deneyebilirsiniz. Tek tek kayıt işlemine göre daha performanslı şekilde bilgileri kayıt ediyor olması gerekir.

Kod: Tümünü seç

var
  Q1: TUniQuery;
  ToplamKayitSayisi: Integer;
  I: Integer;
begin
  Q1 := TUniQuery1.Create(Self);
  try
    Q1.Connection := UniConnection1;
    Q1.SQL.Text := 'insert into table1 (val1, val2) values (:PAR0, :PAR1)';
    Q1.Params[0].DataType := ftInteger;    
    Q1.Params[1].DataType := ftString;     

    ToplamKayitSayisi := 5; // Kaç adet veri kayıt edilecek 
    Q1.Params.ValueCount := ToplamKayitSayisi;

    for I := 1 to ToplamKayitSayisi do
    begin
      // Burada her döngüde olması gereken değerler atanacak
      Q1.Params[0][I].AsInteger  := 1; 
      Q1.Params[1][I].AsString   := 'test 1';
    end;
  
    Q1.Execute(ToplamKayitSayisi);
  finally
    Q1.Free();
  end;
Böyle bir kullanım normal koşullarda kayıt giriş süresini azaltacaktır. Ancak ne kadar fayda sağlayacağını test etmek gerekir.

Son olarak. ProgressBar posizyonunu ilerletmek için aşağıdaki kullanım şeklini değil başka bir sayacı tercih edin.

Kod: Tümünü seç

ProgressBar.Position:=UniQuARSIV.RecNo;
Bu kod arka planda sadece rakam getirmez. Bir prosedür çağırır ve hatırı sayılır işlemler yapar kayıt posizyonunu belirleyebilmek için. Siz zaten toplam kayıt sayısını biliyorsunuz. Basitçe aşağıdaki şekilde bir kullanım işinizi görecek ve zaman tasarrufu açısından bir miktar da olsa faydası olacaktır.

Kod: Tümünü seç

ProgressBar.Position:=I+1;

Kullanıcı avatarı
Commandx
Üye
Mesajlar: 143
Kayıt: 01 Oca 2008 05:34

Re: Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Post SQL

Mesaj gönderen Commandx » 23 Eyl 2019 08:08

freeman35 yazdı:
21 Eyl 2019 04:09
filtre dediğin "where", sıralama, yani senin sort dediğinde bunlar en temel sql komutları. sort, where clause dan dönen result uygulanır.
Post Yazacağıma sort yazmışım.
Biraz inceleme fırsatım oldu fakat nasıl kullanacağımı çözemedim.
İlgilendiğiniz için teşekkür ederim.

ertank yazdı:
22 Eyl 2019 04:54
Merhaba,

UniDAC bileşenleri kullanıyor olmanıza istinaden aşağıdaki örneğe benzer şekilde kodunuzu güncelleyip tek seferde tüm veriyi kayıt etmeyi deneyebilirsiniz. Tek tek kayıt işlemine göre daha performanslı şekilde bilgileri kayıt ediyor olması gerekir.

Kod: Tümünü seç

var
  Q1: TUniQuery;
  ToplamKayitSayisi: Integer;
  I: Integer;
begin
  Q1 := TUniQuery1.Create(Self);
  try
    Q1.Connection := UniConnection1;
    Q1.SQL.Text := 'insert into table1 (val1, val2) values (:PAR0, :PAR1)';
    Q1.Params[0].DataType := ftInteger;    
    Q1.Params[1].DataType := ftString;     

    ToplamKayitSayisi := 5; // Kaç adet veri kayıt edilecek 
    Q1.Params.ValueCount := ToplamKayitSayisi;

    for I := 1 to ToplamKayitSayisi do
    begin
      // Burada her döngüde olması gereken değerler atanacak
      Q1.Params[0][I].AsInteger  := 1; 
      Q1.Params[1][I].AsString   := 'test 1';
    end;
  
    Q1.Execute(ToplamKayitSayisi);
  finally
    Q1.Free();
  end;
Böyle bir kullanım normal koşullarda kayıt giriş süresini azaltacaktır. Ancak ne kadar fayda sağlayacağını test etmek gerekir.

Son olarak. ProgressBar posizyonunu ilerletmek için aşağıdaki kullanım şeklini değil başka bir sayacı tercih edin.

Kod: Tümünü seç

ProgressBar.Position:=UniQuARSIV.RecNo;
Bu kod arka planda sadece rakam getirmez. Bir prosedür çağırır ve hatırı sayılır işlemler yapar kayıt posizyonunu belirleyebilmek için. Siz zaten toplam kayıt sayısını biliyorsunuz. Basitçe aşağıdaki şekilde bir kullanım işinizi görecek ve zaman tasarrufu açısından bir miktar da olsa faydası olacaktır.

Kod: Tümünü seç

ProgressBar.Position:=I+1;
Bu kodu uyarlayacam sonucu yazarım.
Unidac dan çok fazlasıyla memnunum, bu bileşenler hakkını veriyor. hiç yarı yolda bırakmadı.
Doğru, Progressbar recordcount olayı prosedür oluşturuyor progressbar pozisyonu Integere atayım.
Ado bileşenleri zamanindan kalıplaşmış eskiden kalma bir alışkanlık.
İşin mantığını biliyorum da bazı alışkanlıkları terkedemiyor insan.

Bir şey daha keşfettim ; Fieldleri post ederken hepsini value olarak tanımlamışım.
Veri tipimde string, date, integer alanlarım mevcut, hepsine fieldbyname('xxx').VALUE dediğim için alan tanımlama dönüşümü nedeniyle çok hafif bir gecikme oluyor ama bu da verinin gönderilirken ki gecikmenin yanında pek bir şey ifade etmiyor.
http://www.delphibasics.co.uk/RTL.asp?Name=DaysBetween
Zamane tickcount'u
except
ON E: Exception do
Begin
Application.MessageBox(Pchar('Can sıkıntısı '+#13+E.Message),'Hata',MBOKk+MB_ICONWARNING);
Abort;
End;
end;

Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2151
Kayıt: 12 Haz 2003 03:05
Konum: merkez camii yanı

Re: Firebird de Ascend veya Descend Edilen Datayı İnterbase Uzak Sunucumda Tek seferde Post SQL

Mesaj gönderen freeman35 » 24 Eyl 2019 10:30

Script kullanmayı denedin mi? yani 10-20-50-100 yada hepsini(satır fazlaysa bu pek mantıklı olmaz) insert sql i oluşturup, bir seferde execute edebilirsin.
Bir diğer tavsiyem, autocommit i kapat, ve 10-20-50-100 satırda bir manual commit et, hata olursada exceptionda yakalar ve rollback edersin. her posttan sonra commit çok fazla geçikmeye sebep olur.
Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!

Cevapla