C# SQL(Firebird)查询太慢

C# SQL(Firebird)查询太慢,c#,sql,performance,firebird,C#,Sql,Performance,Firebird,到目前为止,我的程序没有任何要求很高的函数,但后来我做的函数需要很多时间。这是一年中第五个月的开始,每天我的数据库都会填充400多个文档(每个文档平均有5-7项(表中有5-7行新行ROBA)。因此,填充一段时间后,计算所有内容需要越来越多的时间,我需要加快速度 目前,完成所有操作大约需要60秒。因此,我想知道是否有任何方法可以加快速度,使用什么,寻找什么。以下是我的函数: private void ucitajStanje() { DataTable dt1 = new DataTabl

到目前为止,我的程序没有任何要求很高的函数,但后来我做的函数需要很多时间。这是一年中第五个月的开始,每天我的数据库都会填充400多个文档(每个文档平均有5-7项(表中有5-7行新行
ROBA
)。因此,填充一段时间后,计算所有内容需要越来越多的时间,我需要加快速度

目前,完成所有操作大约需要60秒。因此,我想知道是否有任何方法可以加快速度,使用什么,寻找什么。以下是我的函数:

private void ucitajStanje()
{
    DataTable dt1 = new DataTable();
    try
    {
        List<List_Int_Decimal> List_roba = new List<List_Int_Decimal>();

        using (FbConnection con = new FbConnection(connectionString_PrirucniMagacin))
        {
            con.Open();
            using (FbCommand cmd = new FbCommand("SELECT ROBAID, KOLICINA FROM STAVKA WHERE VRDOK = 0 AND BRDOK = 1", con))
            {
                FbDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    if (!(dr[0] is DBNull))
                    {
                        List_roba.Add(new List_Int_Decimal { ROBAID = Convert.ToInt16(dr[0]), kolicina = Convert.ToDecimal(dr[1]) });
                    }
                }
            }
            con.Close();
        }

        using (FbConnection con = new FbConnection(connectionString_Baza))
        {
            con.Open();

            //Selektuje stanje u magacinu iz komercijalnog
            using (FbDataAdapter da = new FbDataAdapter("SELECT ROBA.ROBAID, ROBA.KATBR, ROBA.NAZIV, ROBAUMAGACINU.STANJE AS STANJE_KOMERCIJALNO FROM ROBAUMAGACINU INNER JOIN ROBA ON ROBAUMAGACINU.ROBAID = ROBA.ROBAID WHERE MAGACINID = 12 AND VRSTA = 1", con))
            {
                da.Fill(dt1);
            }

            //FIRST SLOW QUERY


            //izracunava stanje kartice robe bez pocetnog stanja iz komercijalnog gde se dodaje na stanje
            using (FbCommand cmd = new FbCommand("SELECT ROBAID, SUM(KOLICINA) FROM STAVKA WHERE VRDOK = 16 AND ROBAID = @Robaid AND MAGACINID = 12 OR VRDOK = 18 AND ROBAID = @Robaid AND MAGACINID = 12 OR VRDOK = 22 AND ROBAID = @Robaid AND MAGACINID = 12 GROUP BY ROBAID", con))
                {
                    cmd.Parameters.Add("@Robaid", FbDbType.Integer);
                    foreach (var robaid in List_roba)
                {
                    cmd.Parameters["@Robaid"].Value = robaid.ROBAID;

                    FbDataReader dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                        if (!(dr[0] is DBNull))
                        {
                            int trenutnaRobaId = Convert.ToInt16(dr[0]);

                            var roba = List_roba.Where(r => r.ROBAID == trenutnaRobaId).FirstOrDefault();
                            if (roba != null)
                            { roba.kolicina = roba.kolicina + Convert.ToDecimal(dr[1]); }
                        }
                    }
                    dr.Close();
                }                    
            }

            //SECOND SLOW QUERY

            //izracunava stanje kartice robe bez pocetnog stanja iz komercijalnog gde se oduzima sa stanja
            using (FbCommand cmd = new FbCommand("SELECT ROBAID, SUM(KOLICINA) FROM STAVKA WHERE VRDOK = 15 AND ROBAID = @Robaid AND MAGACINID = 12 OR VRDOK = 17 AND ROBAID = @Robaid AND MAGACINID = 12 OR VRDOK = 19 AND ROBAID = @Robaid AND MAGACINID = 12 OR VRDOK = 34 AND ROBAID = @Robaid AND MAGACINID = 12 GROUP BY ROBAID", con))
            {
                cmd.Parameters.Add("@Robaid", FbDbType.Integer);
                foreach (var robaid in List_roba)
                {
                    cmd.Parameters["@Robaid"].Value = robaid.ROBAID;

                    FbDataReader dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                        if (!(dr[0] is DBNull))
                        {
                            int trenutnaRobaId = Convert.ToInt16(dr[0]);
                            var roba = List_roba.Where(r => r.ROBAID == trenutnaRobaId).FirstOrDefault();
                            if (roba != null)
                            { roba.kolicina = roba.kolicina - Convert.ToDecimal(dr[1]); }
                        }
                    }
                    dr.Close();
                }                    
            }
            con.Close();
        }
        DataTable dt2 = StaticFunctions.ToDataTable(List_roba);

        var dt = new[] { dt1, dt2 };
        DataTable mergedDT = StaticFunctions.MergeAll(dt, "ROBAID");

        dataGridView1.DataSource = mergedDT;

        dataGridView1.Columns["ROBAID"].Visible = false;
        dataGridView1.Columns["KATBR"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        dataGridView1.Columns["NAZIV"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        dataGridView1.Columns["STANJE_KOMERCIJALNO"].Visible = false;
        dataGridView1.Columns["robaid"].Visible = false;
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}
private void ucitajStanje()
{
DataTable dt1=新DataTable();
尝试
{
List_roba=新列表();
使用(FbConnection con=新FbConnection(connectionString_prirucinimagacin))
{
con.Open();
使用(FbCommand cmd=new FbCommand(“从Statvka中选择ROBAID,KOLICINA,其中VRDOK=0,BRDOK=1”,con))
{
FbDataReader dr=cmd.ExecuteReader();
while(dr.Read())
{
如果(!(dr[0]为DBNull))
{
List_roba.Add(新的List_Int_Decimal{ROBAID=Convert.ToInt16(dr[0]),kolicina=Convert.ToDecimal(dr[1]);
}
}
}
con.Close();
}
使用(FbConnection con=新FbConnection(connectionString_Baza))
{
con.Open();
//我们的目标是建立一个合作伙伴关系
使用(FbDataAdapter da=新FbDataAdapter(“选择ROBA.ROBAID、ROBA.KATBR、ROBA.NAZIV、Robaumagaciu.STANJE作为STANJE_KOMERCIJALNO,从Robaumagaciu内部连接ROBA.ROBAID=ROBA.ROBAID,其中Magacuid=12,VRSTA=1”,con))
{
da.填充(dt1);
}
//第一个慢速查询
//Izracunana stanje kartice长袍与pocetnog stanja iz komercijalnog gde se dodaje na stanje
使用(FbCommand cmd=new FbCommand(“从Statvka中选择ROBAID,SUM(KOLICINA),其中VRDOK=16,ROBAID=@ROBAID AND MAGACINID=12,或VRDOK=18,ROBAID=@ROBAID AND MAGACINID=12,或VRDOK=22,ROBAID=@ROBAID AND MAGACINID=12,按ROBAID分组”,con))
{
cmd.Parameters.Add(“@Robaid”,FbDbType.Integer);
foreach(列表中的var robaid_roba)
{
cmd.Parameters[“@Robaid”].Value=Robaid.Robaid;
FbDataReader dr=cmd.ExecuteReader();
while(dr.Read())
{
如果(!(dr[0]为DBNull))
{
int-trenutnaRobaId=转换为16(dr[0]);
var roba=List_roba.Where(r=>r.ROBAID==trenutnaRobaId.FirstOrDefault();
如果(roba!=null)
{roba.kolicina=roba.kolicina+Convert.ToDecimal(dr[1]);}
}
}
Close博士();
}                    
}
//第二慢查询
//Izracunana stanje kartice长袍是pocetnog stanja iz komercijalnog gde se oduzima sa stanja
使用(FbCommand cmd=new FbCommand(“从Statvka中选择ROBAID,SUM(KOLICINA),其中VRDOK=15,ROBAID=@ROBAID AND MAGACINID=12或VRDOK=17,ROBAID=@ROBAID AND MAGACINID=12或VRDOK=19,ROBAID=@ROBAID AND MAGACINID=12或VRDOK=34,ROBAID=@ROBAID AND MAGACINID=12,按ROBAID分组,con))
{
cmd.Parameters.Add(“@Robaid”,FbDbType.Integer);
foreach(列表中的var robaid_roba)
{
cmd.Parameters[“@Robaid”].Value=Robaid.Robaid;
FbDataReader dr=cmd.ExecuteReader();
while(dr.Read())
{
如果(!(dr[0]为DBNull))
{
int-trenutnaRobaId=转换为16(dr[0]);
var roba=List_roba.Where(r=>r.ROBAID==trenutnaRobaId.FirstOrDefault();
如果(roba!=null)
{roba.kolicina=roba.kolicina-Convert.ToDecimal(dr[1]);}
}
}
Close博士();
}                    
}
con.Close();
}
DataTable dt2=StaticFunctions.ToDataTable(列表A);
var dt=new[]{dt1,dt2};
DataTable mergedDT=StaticFunctions.MergeAll(dt,“ROBAID”);
dataGridView1.DataSource=mergedDT;
dataGridView1.Columns[“ROBAID”]。Visible=false;
dataGridView1.Columns[“KATBR”].AutoSizeMode=DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[“NAZIV”].AutoSizeMode=DataGridViewAutoSizeColumnMode.Fill;
dataGridView1.列[“STANJE_KOMERCIJALNO”]。可见=假;
dataGridView1.Columns[“robaid”]。Visible=false;
}
捕获(例外情况除外)
{
Show(例如ToString());
}
}

尝试避免在循环中调用查询(即反复执行sql):

相反,只需一次性执行查询:


该表中有多少条记录?您可以在ROBAID上创建索引。这是一个非常小的数量。我不使用FireBird,也不确定它的性能。如果可以,请在ROBAID上添加索引,然后重试。表
ROBA
包含4890行,表
Statvka
中有312978行不是很大。我忘了问您是指实际值吗查询速度慢还是foreach速度慢?@wannadream好的,所以我想我在它上面有索引()我想,但如何使用它?嗯,我得到了所有我需要选择的条件
cmd.Parameters[“@Robaid”].Value=Robaid.Robaid;
。如果我这样使用它,我应该在哪里添加它?@Aleksa Risti
  //FIRST SLOW QUERY

  // Loop! 
  foreach (var robaid in List_roba) {
    ...
    // Antipattern: Many a time query calling 
    FbDataReader dr = cmd.ExecuteReader();
    ...
  }
 //FIRST SLOW QUERY (Hope, much faster now)

 //DONE: Keep SQL readable
 string sql = 
    @"SELECT ROBAID, 
             SUM(KOLICINA) 
        FROM STAVKA 
       WHERE MAGACINID = 12 AND
             VRDOK IN (16, 18, 22)
    GROUP BY ROBAID";

 using (FbCommand cmd = new FbCommand(sql, con)) {
   using (FbDataReader dr = cmd.ExecuteReader()) {
     while (dr.Read()) {
       if (dr.IsDBNull(0)) // <- Is it really possible for Id to be null?
         continue;

       int trenutnaRobaId = Convert.ToInt32(dr[0]);

       //TODO: you may want to turn List_roba into Dictionary_roba:
       // if (Dictionary_roba.TryGeValue(trenutnaRobaId, out roba)) 
       //   roba.kolicina = roba.kolicina + Convert.ToDecimal(dr[1]);
       var roba = List_roba
         .Where(r => r.ROBAID == trenutnaRobaId)
         .FirstOrDefault();

       if (roba != null)  
         roba.kolicina = roba.kolicina + Convert.ToDecimal(dr[1]);
     } 
   }
 }
 // In general case, if ROBAID can have duplicates
 var Dictionary_roba = List_roba
   .GroupBy(item => item.ROBAID)
   .ToDictionary(chunk => chunk.Key, 
                 chunk => chunk.First());

 // If ROBAID is unique:
 //var Dictionary_roba = List_roba
 //  .ToDictionary(item => item.ROBAID, item => item); 

 ...

 using (FbCommand cmd = new FbCommand(sql, con)) {
   using (FbDataReader dr = cmd.ExecuteReader()) {
     while (dr.Read()) {
       if (dr.IsDBNull(0)) // <- Is it really possible for Id to be null?
         continue;

       int trenutnaRobaId = Convert.ToInt32(dr[0]);

       // C# 7.0 Syntax - out var; 
       // if you don't have C# 7.0 you have to declare "roba" variable  
       if (Dictionary_roba.TryGeValue(trenutnaRobaId, out var roba))
         roba.kolicina = roba.kolicina + Convert.ToDecimal(dr[1]);
     } 
   }
 }