- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
到目前为止,我编写的程序没有任何要求很高的功能,但后来我制作的功能需要花费很多时间。这是今年第五个月的开始,每天我的数据库都会填充 400 多个文档(每个文档平均有 5-7 个项目(表 ROBA
有 5-7 个新行)。所以在填充了一段时间后,计算所有内容需要越来越多的时间,我需要加快速度。
目前完成所有操作大约需要 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());
}
}
最佳答案
尽量避免在循环中调用查询(即一次又一次执行sql):
//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]);
}
}
}
编辑:如果将 List_roba
变成一个字典(或者至少创建一个临时字典),您可以进一步提高性能,例如
// 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]);
}
}
}
关于c# - SQL (Firebird) 查询太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43797763/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!