如何提高数据库查询的性能?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何提高数据库查询的性能?相关的知识,希望对你有一定的参考价值。
我正在尝试简化代码并使搜索速度更快一些。现在,取决于,它需要超过15秒来填充我的DataGridView。
我试图加入2个SQL句子,但失败了。另外,我不知道如何简化Stock等的检查。我试图将所有信息输入到数组然后将其作为DataGridView Source传递,而不是逐行插入,但对搜索词没有影响。
conn.Open();
mysqlTransaction trans = conn.BeginTransaction();
// Getting the Product
string sql = "SELECT id, typ, generation, configuration, revision"
+ " FROM product"
+ " WHERE typ = '" + comboBox_type.SelectedValue.ToString() + "'";
MySqlCommand cmd = new MySqlCommand(sql, conn, trans);
MySqlDataReader rdr = cmd.ExecuteReader();
List<KeyValuePair<int, string>> productList = new List<KeyValuePair<int, string>>();
while (rdr.Read())
{
string produkt = rdr[1] + "-" + string.Format("{0:X2}", rdr[2]) + string.Format("{0:X2}", rdr[3]) + string.Format("{0:X2}", rdr[4]);
int id = Convert.ToInt32(rdr[0]);
productList.Add(new KeyValuePair<int, string>(id, produkt));
}
rdr.Close();
foreach (KeyValuePair<int, string> productKeyValue in productList)
{
sql = "SELECT COUNT(c.id)"
+ " FROM component_product ctp"
+ " JOIN component c ON ctp.id = c.id"
+ " WHERE ctp.product = " + productKeyValue.Key + " AND c.`status` = 3 AND ctp.outdated = 0";
cmd = new MySqlCommand(sql, conn, trans);
rdr = cmd.ExecuteReader();
int stock = Convert.ToInt32(rdr[0]);
rdr.Close();
int stockDiff = stock, ordered = 0, reserved = 0;
List<string> shortage = new List<string>();
List<string> deliveries = new List<string>();
List<string> planing = new List<string>();
List<CommonHelper.DeliveryEntry> pm_dict = ch.GetProductMovement(productKeyValue.Key, conn, trans);
foreach (CommonHelper.DeliveryEntry de in pm_dict)
{
int amount = de.Amount;
string strDate = CommonHelper.MaterialText.DeliveryTimestamp(de.Timestamp);
bool confirmed = (de.Confirmed == CommonHelper.DeliveryState.Confirmed);
stockDiff += amount;
if (amount >= 0)
{
ordered += amount;
deliveries.Add(CommonHelper.MaterialText.Deliveries(confirmed, amount, stockDiff, strDate));
planing.Add("+" + String.Format("{0,5}", amount) + " (" + strDate + ") Stand: " + stockDiff.ToString());
}
else
{
reserved += amount;
if (stockDiff < 0)
{
shortage.Add(CommonHelper.MaterialText.Shortages(amount, stockDiff, strDate));
}
planing.Add(" " + String.Format("{0,5}", amount) + " (" + strDate + ") Stand: " + stockDiff.ToString());
}
}
string[] rowDate = new string[] {
productKeyValue.Value,
stock.ToString(),
ordered.ToString(),
reserved.ToString(),
string.Join("
", shortage),
string.Join("
", deliveries),
string.Join("
", planing)
};
dataGridView_inventorylist.Rows.Add(rowDate);
}
答案
您可能应该使用连接操作合并您的两个查询。您可以将子查询用作虚拟表。
此聚合(GROUP BY)子查询为每个c.id
值返回一行。
SELECT COUNT(*) count, c.id
FROM component_product ctp
JOIN component c ON ctp.id = c.id
WHERE c.status = 3
AND ctp.outdated = 0
GROUP BY c.id
然后,您将其加入到其他查询中。我使用了LEFT JOIN
,因此整个查询将报告没有计数的项目。一个简单的JOIN
抑制没有计数的行。
尝试这样的事情:
SELECT count.count,
p.id, p.typ, p.generation, p.configuration, p.revision
FROM product p
LEFT JOIN (
SELECT COUNT(*) count, c.id
FROM component_product ctp
JOIN component c ON ctp.id = c.id
WHERE c.status = 3
AND ctp.outdated = 0
GROUP BY c.id
) count ON p.id = count.id
WHERE typ = '" + comboBox_type.SelectedValue.ToString() + "'";
然后,使用这一个查询的行填充网格。完全摆脱productlist
集合,摆脱对该集合的每个元素运行查询的循环。换句话说,只需一个查询即可检索所需内容,而不是一个加一个产品。这应该可以解决您的性能问题。
以上是关于如何提高数据库查询的性能?的主要内容,如果未能解决你的问题,请参考以下文章