Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
10-05-2018, Saat: 00:21
(Son Düzenleme: 10-05-2018, Saat: 14:01, Düzenleyen: canbir.)
İki farklı Stored procedure ile yaptığım sorguyu birleştirmek istiyorum. Birşeyler yaptım ama iyi mi yaptım, kötü mü yaptım bilemedim.
AKTIF_DURUMU alanında 3 tip veri kaydettiriyorum:Aktif, Pasif,Ayrıldı. Sp'ler ile aktif ve ayrılış yapmamış(aktif+pasif toplamı) personellerin sayılarını alıyorum.
1. sp:// aktif çalışanların sayısını alıyorum.
begin
select count(*) from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
AND AKTIF_DURUMU='Aktif'
INTO :AKTIF;
suspend;
end
2. sp:// Ayrılış yapmamış personel sayılarını alıyorum.
begin
select count(*) from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
AND AKTIF_DURUMU<>'Ayrıldı'
INTO :MEVCUT;
suspend;
end
Birleştirdiğim Sp:
begin
select (select count(*) from personel where AKTIF_DURUMU='Aktif') as AKTIF, (select count(*) from personel where AKTIF_DURUMU<>'Ayrıldı') as MEVCUT from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
INTO :AKTIF,:MEVCUT;
suspend;
end
Bu şekildeki iç içe select sorgularında benim kullandığım şekilde count kullanılır mı? firebird sorguyu çalıştırmaya nereden başlar? Önce ana select where koşulunu mu yoksa ana select içine yazdığım selectleri mi? Önce ana select içindeki select sorguları ile -count- alanları çekiyorsa bulunan sayılar, ana selectin where şartına göre yeniden mi düzenleniyor? Ben ilk önce ana select cümlesinin where koşulunun işletildiğini düşündüğümden iki farklı sorguya göre birleştirdiğim sp'nin daha iyi olacağını düşünüyorum. Yaptığım şey mantıklı mı, hız ve performans açısından bir faydası olur mu?
Yorumları: 861
Konuları: 35
Kayıt Tarihi: 12-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 3.759 Uzman
Sizin durumunuzda hız ve performans için tek sorgu yada 2 sorgu pekte önemli değil bence, zira bir programa kaç tane personel tanıtabilirsiniz ki ? binlerce, onbinlerce olmayacak sonuçta. Ama, kod kısa, derli toplu olsun derseniz elbetteki yararı olacaktır.
Bunun yanında ben olsam AKTIF_DURUMU alanını smallint gibi bişi yapardım (bir tek bu tablo için düşünmeyin), 0:aktif 1:pasif 2:ayrıldı vs.vs. gibi. Bunu on binlerce kayıt girilen fatura tablosuna tablosunda kullandığınızı düşünün, türü varchar(10) deyip 10 byte kullanmak var, türü smallint deyip 2 byte kullanmak var, 10k kayıtta her bir byte size 10k ek yük getirir şeklinde düşünün, bunun yanında ağdan bağlanan kullanıcılar içinde türü=0 demek var, türü=alış faturası demek var, buda size her bir sorguda fazladan ağ trafiğine ek yük bindirmek olacaktır.
Yorumları: 453
Konuları: 14
Kayıt Tarihi: 07-09-2016
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.1
- Delphi XE7
- Delphi XE2
- Delphi 7
Rep Puanı: 1.833 Programcı
(10-05-2018, Saat: 00:21)canbir Adlı Kullanıcıdan Alıntı: İki farklı Stored procedure ile yaptığım sorguyu birleştirmek istiyorum. Birşeyler yaptım ama iyi mi yaptım, faydasız veya kötü birşey mi yaptım bilemedim. Yaptığım şey mantıklı mı, hız ve performans açısından bir faydası olur mu?
AKTIF_DURUMU alanında 3 tip veri kaydettiriyorum:Aktif, Pasif,Ayrıldı. Sp'ler ile aktif ve ayrılış yapmamış(aktif+pasif toplamı) personellerin sayılarını alıyorum.
1. sp:// aktif çalışanların sayısını alıyorum.
begin
select count(*) from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
AND AKTIF_DURUMU='Aktif'
INTO :AKTIF;
suspend;
end
2. sp:// Ayrılış yapmamış personel sayılarını alıyorum.
begin
select count(*) from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
AND AKTIF_DURUMU<>'Ayrıldı'
INTO :MEVCUT;
suspend;
end
Birleştirdiğim Sp:
begin
select (select count(*) from personel where AKTIF_DURUMU='Aktif') as AKTIF, (select count(*) from personel where AKTIF_DURUMU<>'Ayrıldı') as MEVCUT from personel
where UNVANI=:UNVANI
AND GOREV_YERI=:GOREV_YERI
INTO :AKTIF,:MEVCUT;
suspend;
end
Bir count sorgusu tek satır döndürmesi gerekirken sizin sorgunuz potansiyel olarak onlarca satır döndürebilir ve performans olarak da pek iyi değil açıkçası. Aşağıdaki kodu bir inceleyin:
begin
select
count(case when aktif_durumu='Aktif' then id end) as aktif,
count(case when aktif_durumu<>'Ayrıldı' then id end) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
10-05-2018, Saat: 12:32
(Son Düzenleme: 10-05-2018, Saat: 12:33, Düzenleyen: canbir.)
(10-05-2018, Saat: 09:26)edo Adlı Kullanıcıdan Alıntı: Bir count sorgusu tek satır döndürmesi gerekirken sizin sorgunuz potansiyel olarak onlarca satır döndürebilir ve performans olarak da pek iyi değil açıkçası. Aşağıdaki kodu bir inceleyin:
begin
select
count(case when aktif_durumu='Aktif' then id end) as aktif,
count(case when aktif_durumu<>'Ayrıldı' then id end) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Yanlış yorumlamış olabilirim ama, önerdiğiniz kodun sonuç olarak şöyle uygulanacağını düşünüyorum.
begin
select
count(ID) as aktif,
count(ID) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Bu durumda da hem aktif hem mevcut için aynı sayıyı vermez mi?
Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
(10-05-2018, Saat: 09:21)esistem Adlı Kullanıcıdan Alıntı: Sizin durumunuzda hız ve performans için tek sorgu yada 2 sorgu pekte önemli değil bence, zira bir programa kaç tane personel tanıtabilirsiniz ki ? binlerce, onbinlerce olmayacak sonuçta. Ama, kod kısa, derli toplu olsun derseniz elbetteki yararı olacaktır.
Bunun yanında ben olsam AKTIF_DURUMU alanını smallint gibi bişi yapardım (bir tek bu tablo için düşünmeyin), 0:aktif 1:pasif 2:ayrıldı vs.vs. gibi. Bunu on binlerce kayıt girilen fatura tablosuna tablosunda kullandığınızı düşünün, türü varchar(10) deyip 10 byte kullanmak var, türü smallint deyip 2 byte kullanmak var, 10k kayıtta her bir byte size 10k ek yük getirir şeklinde düşünün, bunun yanında ağdan bağlanan kullanıcılar içinde türü=0 demek var, türü=alış faturası demek var, buda size her bir sorguda fazladan ağ trafiğine ek yük bindirmek olacaktır.
Aslında bu kodu çok yoğun şekilde kullanacağım, ayrıca personel sayısı, görev yeri ve unvan sayısı da fazla miktarda. Yazdığım sorgunun ne getirip götüreceğinden emin olamamamın asıl nedeni, select sorgusunun işleyisiyle alakalı. Eğer ilk önce where bölümü işletiliyorsa olumlu bir etkisi olur, fakat ilk önce select ile çekilen alanlar çekiliyorsa, orada iki adet ek select cümlesi olduğundan o zaman bir fark olmaz. Bu durumda bile sizin de dediğiniz gibi daha derli toplu olması açısından tek sp olarak kullanmak daha mantıklı.
Diğer konu için de aslında ben de en az yer işgal edecek şekilde alanlarımı tanımlamaya gayret ediyorum. Kullanıcıya dbcombobox ile seçim yaptırmayı planlıyordum. Sizin uyarınız üzerine veri tipini değiştirip kullanıcıya da dbradiogroup ile seçim yaptırsam nasıl olur diye bir bakayım.
Yorum yapan arkadaşlara teşekkür ediyorum. (+ rep)
Yorumları: 453
Konuları: 14
Kayıt Tarihi: 07-09-2016
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.1
- Delphi XE7
- Delphi XE2
- Delphi 7
Rep Puanı: 1.833 Programcı
(10-05-2018, Saat: 12:32)canbir Adlı Kullanıcıdan Alıntı: (10-05-2018, Saat: 09:26)edo Adlı Kullanıcıdan Alıntı: Bir count sorgusu tek satır döndürmesi gerekirken sizin sorgunuz potansiyel olarak onlarca satır döndürebilir ve performans olarak da pek iyi değil açıkçası. Aşağıdaki kodu bir inceleyin:
begin
select
count(case when aktif_durumu='Aktif' then id end) as aktif,
count(case when aktif_durumu<>'Ayrıldı' then id end) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Yanlış yorumlamış olabilirim ama, önerdiğiniz kodun sonuç olarak şöyle uygulanacağını düşünüyorum.
begin
select
count(ID) as aktif,
count(ID) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Bu durumda da hem aktif hem mevcut için aynı sayıyı vermez mi?
Sizin kodunuz iki kolonda da aynı veriyi döndürürken, benim size söylediğim yöntem ayrı ayrı aktif ve mevcut sayısı verir. Uzak yakın alakası yok yani
Yorumları: 1.702
Konuları: 20
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 19.330 Üstad
10-05-2018, Saat: 14:16
(Son Düzenleme: 10-05-2018, Saat: 14:19, Düzenleyen: mrmarman.)
önce where ile ürün tablo elde edilir sonra bu ürün tablodan select içindeki select satırları tetiklenir. Gönlünüz rahat olsun.
SQL performans deyince akla ilk gelen index'lerdir. Bunları ihmal etmeyin.
where kısmına tarih aralığı gibi sınırlayıcı öncü satırlar çabuk elemeye yardımcı olur.
where kısmında hesaplama yaptırmaktan kaçının, yani where a_field * b_field >100 gibi hesaplardan bahis.
select ile gereksiz field çekmeyin, sadeleştirin. ortak select procedure yapınız varsa bu ortak procedure / function için parametreler ile donatıp join table ve/veya select field sayısını minimuma indirgemeye çalışın. (sql params gibi yanlış algılamayın)
Bunlara dikkat ederseniz sql performansı artacaktır.
Saygılarımla
Muharrem ARMAN
Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
(10-05-2018, Saat: 14:01)edo Adlı Kullanıcıdan Alıntı: (10-05-2018, Saat: 12:32)canbir Adlı Kullanıcıdan Alıntı: Yanlış yorumlamış olabilirim ama, önerdiğiniz kodun sonuç olarak şöyle uygulanacağını düşünüyorum.
begin
select
count(ID) as aktif,
count(ID) as mevcut
from personel
where unvani=:unvani and gorev_yeri=:gorev_yeri
into :aktif,:mevcut;
suspend;
end
Bu durumda da hem aktif hem mevcut için aynı sayıyı vermez mi?
Sizin kodunuz iki kolonda da aynı veriyi döndürürken, benim size söylediğim yöntem ayrı ayrı aktif ve mevcut sayısı verir. Uzak yakın alakası yok yani
Doğrusu hiç aklıma yatmamıştı ama ikinci yazınız üzerine veritabanına kayıt oluşturup denedim. Önerdiğiniz kod gerçekten de doğru sonuç veriyor. Ben üstte yazdığım gibi olacağını düşünmüştüm ama demek ki yanlış düşünmüşüm. Yardımınız için çok teşekkür ederim.
Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
(10-05-2018, Saat: 14:16)mrmarman Adlı Kullanıcıdan Alıntı: önce where ile ürün tablo elde edilir sonra bu ürün tablodan select içindeki select satırları tetiklenir. Gönlünüz rahat olsun.
SQL performans deyince akla ilk gelen index'lerdir. Bunları ihmal etmeyin.
where kısmına tarih aralığı gibi sınırlayıcı öncü satırlar çabuk elemeye yardımcı olur.
where kısmında hesaplama yaptırmaktan kaçının, yani where a_field * b_field >100 gibi hesaplardan bahis.
select ile gereksiz field çekmeyin, sadeleştirin. ortak select procedure yapınız varsa bu ortak procedure / function için parametreler ile donatıp join table ve/veya select field sayısını minimuma indirgemeye çalışın. (sql params gibi yanlış algılamayın)
Bunlara dikkat ederseniz sql performansı artacaktır.
Bilgilendirme için teşekkür ederim. İlk mesajımdaki merak ettiğim konular artık kafamı kurcalamayacak.
Yorumları: 453
Konuları: 14
Kayıt Tarihi: 07-09-2016
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.1
- Delphi XE7
- Delphi XE2
- Delphi 7
Rep Puanı: 1.833 Programcı
(10-05-2018, Saat: 15:41)canbir Adlı Kullanıcıdan Alıntı: (10-05-2018, Saat: 14:16)mrmarman Adlı Kullanıcıdan Alıntı: önce where ile ürün tablo elde edilir sonra bu ürün tablodan select içindeki select satırları tetiklenir. Gönlünüz rahat olsun.
SQL performans deyince akla ilk gelen index'lerdir. Bunları ihmal etmeyin.
where kısmına tarih aralığı gibi sınırlayıcı öncü satırlar çabuk elemeye yardımcı olur.
where kısmında hesaplama yaptırmaktan kaçının, yani where a_field * b_field >100 gibi hesaplardan bahis.
select ile gereksiz field çekmeyin, sadeleştirin. ortak select procedure yapınız varsa bu ortak procedure / function için parametreler ile donatıp join table ve/veya select field sayısını minimuma indirgemeye çalışın. (sql params gibi yanlış algılamayın)
Bunlara dikkat ederseniz sql performansı artacaktır.
Bilgilendirme için teşekkür ederim. İlk mesajımdaki merak ettiğim konular artık kafamı kurcalamayacak.
Aman hocam, bunlar en önemli konular. Bunların kafanızı bolca kurcalaması lazım. Sorgu optimizasyonu, doğru/yanlış index kullanımı vs. bunları bol bol araştırın. Yoksa veritabanını en güçlü sunucuya koysanız yine kaynakları tüketirsiniz
|