ASP.Net ile veri çekme testleri..

geri

Zamanında overclock ile epeyce uğraştım, çok fazla sayıda donanımı deneme ve test etme imkanı buldum. Sonrasında yazılım tarafı ağır basınca overclock işini maziye gömdüm. Kaç zamandır acaba DataTable mi kullansam, foreach mı kullansam veya DataAdapter mi kullansamın hesabını yapıyordum, diğer yandan acaba hangisi daha performanslı çalışır veya kullanıcı tarafında hangisi daha sorunsuz görüntülenebilir gibi düşünceler içerisindeydim. Madem eski hız aşırtmacılardanım kendimce bir test (benchmark) platformu hazırlayıp işe koyulayım dedim. Belki yanlış işlemler yapmış olabilirim, göz ardı ettiğim noktalar olabilir bunları eğer paylaşırsanız çok sevinirim.

Test sistemi;

Acer 5920G Dizüstü Bilgisayar (T7100 @ 1,8Ghz İşlemci, 4GB 800Mhz Bellek)
Windows Vista Ultimate (32-Bit) (Güncel), Internet Explorer 7, Mssql 2005, FrameWork 3,5 (Güncel), Visual Studio 2008

**Test hakkında:
**Sql server, IIS ve İstemci aynı bilgisayardır, sonuçları ms cinsinden etkilemiştir fakat tüm testler için aynı ortam olduğu için % olarak çok bir fark olacağını sanmıyorum.Testleri en çok kullanılan veri listeleme nesneleri olan GridView ve DataList içinde listeledim.Her testi 3 kez tekrarlayarak ortalamasını aldıktan sonra kayda geçtim.
SQL Server Profiler sadece ilgili testi yaparken açıktı, diğer durumlarda kapalı.
Grafiklerdeki veriler milisaniye (ms) cinsinden olup, Sql S.P. SQL Server Profiler kısalıtılmış halidir.
Testler sırasında  EnableViewState="false" durumundadır, nedenlerin başında foreach döngüsünde viewstate boşken gridview ve datalist' te dolu olması. Haksızlık olmasın diye kapattım.
Sırasıyla 1000,10.000 ve 100.000 kayıt üzerinde denemeler yapılmıştır.
Testler arasındaki geçişleri // işaretlerini kaldırarak ve pageload daki method ismini değiştirerek gerçekleştirdim.
Hatırlatma: Milisaniye cinsinden değerler azaldıkça performansın arttığını anlıyoruz.

**Testte kullanılan kodlar ve tablonun yapısı:
**Testte Vegawin ticari yazılımının kullanıcı işlemlerini loglayan tablosunu kullandım, içerisinde 530.000 adet kayıt bulunan bir tablo, test sırasında dışarıyla bağlantısı olmadığından herhangi bir ekleme yada silme işlemi söz konusu değildi.

CREATE TABLE [dbo].[TBLLOG] (
  [IND] int IDENTITY(100, 1) NOT NULL,
  [FIND] int NULL,
  [DIND] int NULL,
  [PID] smallint NULL,
  [TARIH] datetime NULL,
  [MAKINE] nvarchar(50) COLLATE Turkish_CI_AS NULL,
  [USERID] int NULL,
  [BELGE] int NULL,
  [BELGENO] int NULL,
  [EYLEM] int NULL,
  [ACIKLAMA] nvarchar(100) COLLATE Turkish_CI_AS NULL
)
ON [PRIMARY]
GO
[/html]

Yeri gelmişken bana Object Oriented konusunda yol gösteren ve herzaman vakit ayırıp sorularımı cevaplayan Yunus Emre arkadaşıma teşekkürlerimi sunuyorum.

Class.cs
[/html]
public class veritabani
    {
        static private string baglanti()
        {
            return @"Data Source=sunucu;Initial Catalog=veritabani;Persist Security Info=True;User ID=kullaniciadi;Password=sifre;pooling=true";
        }
        public static DataTable DataTableGetir(string strSQL)
        {
            SqlConnection conn = new SqlConnection(baglanti());
            SqlCommand cmd = new SqlCommand(strSQL, conn);
            cmd.CommandTimeout = 0;
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            try
            {
                da.Fill(ds, "TABLE");
                return ds.Tables["TABLE"];
            }
            catch
            {
            }
            finally
            {
                if (conn != null && conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
                conn = null;
            }
        }
    }
[/html]
[/html]
public partial class _Default : System.Web.UI.Page 
{
    string kayitsayisi="100000";
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            griddoldur2();
        }
    }

    protected void griddoldur1() {
        DateTime baslangic = DateTime.Now;
        
        DataTable dt = veritabani.DataTableGetir("Select top "+kayitsayisi+" * from TBLLOG");
        GridView1.DataSource = dt;
        GridView1.DataBind();

        //foreach (DataRow dr in dt.Rows)
        //{
        //Response.Write("");
        //Response.Write("");
        //Response.Write("" + dr["IND"].ToString() + " - " + dr["FIND"].ToString() + " - 
        " + dr["DIND"].ToString() + " - " + dr["PID"].ToString() + " - " + dr["TARIH"].ToString() + " - 
        " + dr["MAKINE"].ToString() + " - " + dr["USERID"].ToString() + " - " + dr["BELGE"].ToString() + " - 
        " + dr["BELGENO"].ToString() + " - " + dr["EYLEM"].ToString() + " - " + dr["ACIKLAMA"].ToString() + "");
        //}

        DateTime bitis = DateTime.Now;
        TimeSpan fark = bitis - baslangic;
        sonuc.Text = fark.TotalMilliseconds.ToString() +" mili saniye";
    }

    protected void griddoldur2() {
        DateTime baslangic = DateTime.Now;
        SqlConnection sqlConn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["baglanti"].ToString());
        SqlDataAdapter sqlAdap = new SqlDataAdapter("Select top " + kayitsayisi + " * from TBLLOG", sqlConn);
        DataSet Ds = new DataSet();
        sqlAdap.Fill(Ds);
        GridView1.DataSource = Ds;
        GridView1.DataBind();
        DateTime bitis = DateTime.Now;
        TimeSpan fark = bitis - baslangic;
        sonuc.Text = fark.TotalMilliseconds.ToString() + " mili saniye";
    }
}
[/html]


Grafiklerle test sonuçları


Test sonuçları ve gözlemlerim:
Kayıt sayısı arttıkça foreach döngüsünün başarısıda ciddi anlamda artıyor. 
Ekstra bir ayar yapmadığımdan dolayı veriler geldikçe tarayıcıya basılıyor ve bu 
sayede kullanıcı diğer yöntemlerde verinin tam yüklenmesini beklerken bu yöntemde uzun süreli beklemeden 
kurtulmuş oluyor, kayıtların tamamı döndükçe döndükçe geliyor ve aynı zamanda 
düşük konfigürasyonlu bilgisayarlarda oluşacak olan donma ve yanıt vermeme 
durumu ortadan kalkmış oluyor. 100.000 kayıt 
ciddi bir rakam uygulamada belkide hiç karşılaşılmayacak bir rakam fakat neler 
olduğunu görmek adına denemek istedim, veriler ekrana basılırken ve basıldıktan 
sonra zaman zaman tarayıcınızın cevap vermemesine sebep oluyor, yinede sorunsuz 
bir şekilde listeleniyor. Burada 
belkide sql sunucu, istemci ve iis in bir arada olmasıda önemli bir faktör 
olarak görülebilir fakat bellek kullanımı ve işlemci kullanımına baktığımda 
anormal bir durum söz konusu değildi. Bu sadece bir testti, test sonuçlarından 
sonra foreach çok daha performnslı diye bu yöntemi kullanıp, gridview ve 
datalist gibi nesnelerin nimetlerinden yararlanmamak tabiki söz konusu olamaz. 
Bu kadar çok kaydı ciddi raporlarda almadıktan sonra kolay kolay web de 
karşımıza sanmıyorumki çıksın, az kayıt sayısında da devasa farklar oluşmuyor. 
Burda dikkatimi çeken nokta ise DataTable nin performansı oldu, 1000 ve 10.000 
kayıtta DataAdapter' e fark atıp foreach ile kafa kafa ya giderken 100.000 
kayıtta tepetaklak olması beni şaşırttı. İlk fırsatta bu testi yeniden yapıp 
sonuçları paylaşacağım. Asıl bundan sonra yapacak olduğum Insert ve Update 
işlemleri beni çok meraklandırıyor, bakalım bu testlerde neler olacak. Kendime 
göre çıkardığım sonuçta DataTable kullanmak en sağlıklısı, ama unutmayınki her 
yiğidin bir yoğurt yiğişi vardır. :)
2009-04-11 | asp-net