Firebird sorgu hiz sorunu

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
oyle
Üye
Mesajlar: 137
Kayıt: 17 Eki 2006 05:53

Firebird sorgu hiz sorunu

Mesaj gönderen oyle »

Merhabalar,
4.400 kayitli bir tablom var.

Kod: Tümünü seç

 Close;
 SelectSql.Clear;
 SelectSql.Add('select h.hesapkodu,h.hesapadi,h.hesaptipi,');
 SelectSql.Add('sum(coalesce(f.borc,0)) borc,');
 SelectSql.Add('sum(coalesce(f.alacak,0)) alacak,');
SelectSql.Add('from muhfishareket f');
 SelectSql.Add(' right join hesapplani h on (');
 SelectSql.Add('LEFT(f.hesapkodu,CHAR_LENGTH (h.hesapkodu))=h.hesapkodu');
 SelectSql.Add('and CHAR_LENGTH(h.hesapkodu)>=1)');
bu kodla rapor aliyorum.
sonucta bana;

Kod: Tümünü seç

hesap kodu -------              borc    alacak
100            --------              69.161       0
100 01       -------              68.762       0
100 02       --------                   399       0
gibi bi sonuc veriyor. Ama raporun calismasi 6 saniye suruyor.
Sorgu icindeki

Kod: Tümünü seç

 SelectSql.Add('LEFT(f.hesapkodu,CHAR_LENGTH (h.hesapkodu))=h.hesapkodu');
satirini kaldirdigimda ise 1 saniyeden daha kisa zamanda sonucu veriyor.
Gerekli index leri ayarladim. Bu sorguyu hizlandirmanin bir yolu varmi acaba?
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7603
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Re: Firebird sorgu hiz sorunu

Mesaj gönderen mussimsek »

Merhaba,

Sanırım tabloların direk foreign key ile bağlı değil. Bu tarz fonksiyonların çalışması da biraz vakit alabilir.

Yapını biraz değiştirip, f ve h tablolarını direk alanlar üzerinden bağlayabilmen lazım. Aradaki ilişkiyi ve alanları anlatırsan daha net birşeyler söyleyebilirim.

Kolay gelsin.
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Re: Firebird sorgu hiz sorunu

Mesaj gönderen Hakan Can »

WHERE şartında LIKE komutunu kullanırsan hızlanabilir:

Kod: Tümünü seç

WHERE f.hesapkodu LIKE h.hesapkodu || '%'
gibi.
oyle
Üye
Mesajlar: 137
Kayıt: 17 Eki 2006 05:53

Re: Firebird sorgu hiz sorunu

Mesaj gönderen oyle »

Oncelikle ilginize tesekkur ederim.
WHERE şartında LIKE komutunu kullanırsan hızlanabilir:
Bunu denedim hiz konusunda pek bi degisiklik olmadi.

Benim yapmak istedigim mizan raporu almak
bir hesap plani tablom var birde fis hareketleri tablom.
tum hesap plani sirayla listelenecek yanlarinda da hareketler tablosundan cekilmis veriler olacak. tabiki toplamlar seklinde.
hesap no 1 hesabin toplami 100
hesap no 10 hesabin toplami 70
hesap no 100 hesabin toplami 30

yukari dogru cikildikca (100 den 1 e dogru) ilgili hesaplarin toplamida bir ustte atacak.
ornek:
30,
30+70
100 gibi
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Re: Firebird sorgu hiz sorunu

Mesaj gönderen Hakan Can »

Bildiğim iki tane ana yöntem var mizan raporunu alabilmek için.

Bir tanesi Hesap Planına triggerlarla BORC, ALACAK bilgilerini yazmak. Bu mizan raporunun tabloda direk gözükmesi anlamına geliyor. Triggerlarda verdiğim örnekteki LIKE komutunu kullanarak UPDATE-INSERT edebilirsin.

Diğeri ise şu an kullandığın yöntem (iki tabloyu JOIN edip SELECT yapmak).

İkinci yöntem veritabanı tasarımı açısından sonuçta daha ideal.

Ama sorun 4.400 kayıtlı tabloda query'nin 6 saniye sürmesi. Kayıt sayısı yüzbinleri geçince muhtemelen saatleri bulacak.

Sebebi ise query'nin herbir hesap planı kaydı için fişler tablosunu belki de baştan sona taraması.

Benim aklıma DERIVED TABLES yaklaşımıyla bir çözüm aramak geliyor. Yani bu hesap yapılan satır sayısını minimuma indirmeye çalışmak geliyor zira yüzbinlerce kayıt dahi olsa hiçbir query'nin 5-10 saniyeyi geçmemesi gerekiyor. Yoksa kullanıcıya (müşteriye) anlatamazsın olan biteni.

Eğer bahsettiğin iki tabloyu (Hesap Planı ve Fiş Hareketleri) bizimle paylaşabilirsen (paradox, dbase, GDB vs. olarak kaydedip..) direk testler (query) yapıp yardımcı olmaya çalışabiliriz.

İyi çalışmalar.
Kullanıcı avatarı
csunguray
Üye
Mesajlar: 855
Kayıt: 09 Ara 2006 05:08
Konum: Adana
İletişim:

Re: Firebird sorgu hiz sorunu

Mesaj gönderen csunguray »

Kod: Tümünü seç

  LEFT(f.hesapkodu,CHAR_LENGTH (h.hesapkodu))=h.hesapkodu
yerine

Kod: Tümünü seç

  f.hesapkodu between h.hesapkodu and h.hesapkodu || 'zzzzz'
gibi bir kod deneyin. Kanaatimce between kullanınca otomatikman indekslerden faydalanacaktir.
C. Sunguray
csunguray at netbilisim.kom
Net Bilişim Hizmetleri

Sıradan her programcı bilgisayarın anlayabileceği kodlar yazabilir.
Sadece iyi programcılar insanların da anlayabileceği kodlar yazarlar.
Martin Fowler (http://martinfowler.com/)
oyle
Üye
Mesajlar: 137
Kayıt: 17 Eki 2006 05:53

Re: Firebird sorgu hiz sorunu

Mesaj gönderen oyle »

@hakan can ,
ilk dediginiz yonteme gore yaptim. hesap planina borc, alacak alani olusturdum. rapor alacagim zaman stored procedure ile hareket gormus hesaplari toplatip hesap planina attim. oradan da siralattim. suan hiz 1 saniyenin altina indi. 50 bine yakin kayit olusturdum. ve hiz da bir sorun yok gibi. 4 binle 50 bin arasinda hic hiz farki yok sayilir. ikiside 1 saniyenin altinda (700-800 milisaniye civari) gerci hala bu bana yeterli gelmiyor ama 6 saniyeden iyi dir :)

@csunguray ;
Kod: Tümünü seç
f.hesapkodu between h.hesapkodu and h.hesapkodu || 'zzzzz'


gibi bir kod deneyin. Kanaatimce between kullanınca otomatikman indekslerden faydalanacaktir.
Bunu denedim ama indexleri kullanmiyor. plan da natural plan seklinde gozukuyor.

Ben kodla sorgu yaparken index secimi yapabilir miyim acaba? Eğer kendim yapabilirsem indexleri kullandirttirabilirim.
Bi site de asagidaki gibi bir kod gormustum. Ama bi turlu benzerini yapamadim.

Kod: Tümünü seç

select 
    PROC.PROC, 
    PROC.EXP1 as EXPE, 
    PROC.ACTO, 
    PROC.DEMA, 
    PROC.OBSE, 
    TPRO.DSCR as D_TPRO 
  from PROC left outer join TPRO on PROC.TPRO = TPRO.TPRO 
 where 
   (exists ( 
       select MOVI.PROC from MOVI 
        where MOVI.TIPO = 'B' 
          and MOVI.PROC = PROC.PROC 
        PLAN (MOVI index MOVI_PROC, MOVI_TIPO)             -- sanirim burasi index tanim kismi ! 
          ) 
   ) 
order by lower(PROC.ACTO) 

Birde
100
100 01
100 02
100 02 01 .... seklinde devam eden hesap planim var. ben bu hesap planinda iki hesap arasinda listeleme yapmak istiyorum. Örn: 100 02 ile 200 01 02 arasindaki hesaplari gormek istiyorum. alan sayisal olmadigi icin isler karisiyor biraz.

İyi calismalar.
Kullanıcı avatarı
csunguray
Üye
Mesajlar: 855
Kayıt: 09 Ara 2006 05:08
Konum: Adana
İletişim:

Re: Firebird sorgu hiz sorunu

Mesaj gönderen csunguray »

Arkadaşlar. Ben genelde MS-SQL kullanıyorum, 1-2 projemde de müşteri istediği için MySQL kullandım. Gerçek bir projede hiç Firebird kullanmadım. Normalde Between ile yapılacak bir filtreleme işleminde mevcut indekslerden yararlanılmasını bekleriz. Siz beklemiyor musunuz? Firebird bunu yapamıyor mu? Veya arkadaşın sorduğu gibi sorguyu bir indeksi kullanmaya zorlayamıyor muyuz?
C. Sunguray
csunguray at netbilisim.kom
Net Bilişim Hizmetleri

Sıradan her programcı bilgisayarın anlayabileceği kodlar yazabilir.
Sadece iyi programcılar insanların da anlayabileceği kodlar yazarlar.
Martin Fowler (http://martinfowler.com/)
Cevapla