【问题标题】:Performance differences in c#c#中的性能差异
【发布时间】:2023-04-09 03:54:01
【问题描述】:

我有以下代码。有时执行此代码需要更长的时间。 需要改进代码。

//Get products from DB
DataTable dtProducts = GetAllProducts();

if(dtProducts !=null && dtProducts.Rows.Count >0)
{

dtProducts .DefaultView.RowFilter = null;
dtProducts .DefaultView.RowFilter = " product_id = '" +product_id.Trim() + "'";

DataTable dtProductCount = dtProducts .DefaultView.ToTable();

       if (dtProductCount != null && dtProductCount.Rows.Count > 0)
       {
           object obj = dtProductCount.Compute("SUM(qty)", "");
           if (!Convert.IsDBNull(obj))
           {
              int qtyProd = Convert.ToInt32(obj);
           }
       }

}

这里有任何性能改进的范围吗? 我们可以在数据表中使用 Any() 来代替 Count

【问题讨论】:

  • 我确信您观察到的性能差异与您无法控制的事情有关,例如当时数据库或网络发生的其他事情。
  • 为什么不首先运行select sum(qty) from db_table where product_id=@product_id_param
  • 我假设 GetAllProducts 查询数据库,如果是这种情况,您想要专注于加速而不是 if 语句。 Count > 0Any 之间的差异可能可以忽略不计,我怀疑编译器甚至可能将它们编译成相同的代码,尽管我不确定。
  • 如果这里的设计是通过 GetAllProducts() 获取所有内容,然后在客户端中对该结果执行过滤 - 不要,它很昂贵并且可能存在扩展问题。为此使用数据库本身,这是它的设计目的。

标签: c# asp.net performance


【解决方案1】:

一个明确的改进是将过滤条件 product_id = '" +product_id.Trim() + "' 包含在 SQL 查询本身的 WHERE 子句中,从而只返回所需的数据集而不是所有内容

select * from products
where product_id = @product_id

根据您的评论 因为此代码在我获得产品 ID 的每个循环中运行...然后从您的 for loop 收集所有 product_id 并创建一个类似 @ 的列表987654326@ 然后使用 IN 运算符仅在查询中使用它。

【讨论】:

  • @TheLethalCoder,这是初稿
  • @Rahul,不能按照你的建议去做。因为这段代码在我获得产品 ID 的 for each 循环中运行
  • @Rahul,这不会按照业务逻辑工作。我需要分别获取每个产品数据 qtyProd 变量。类似的逻辑还有很多,只分享比较耗时的部分。
【解决方案2】:

数据库本身专门用于数据聚合,因此您可以为其交付该工作:

public DataTable GetProductQuantitySummary(int? productId)
{
    using (var cn = new SqlConnection("...."))
    using (var cm = new SqlCommand   ("", cn))
    {
        cn.Open();
        cm.CommandText = @"
            SELECT   product_id, SUM(qty) SumQty
            FROM     Products
            WHERE    product_id = @product_id OR @product_id IS NULL
            GROUP BY product_id";
        cm.Parameters.AddWithValue("@product_id", (object) productId ?? DBNull.Value);

        var table = new DataTable();
        using (var reader = cm.ExecuteReader())
        {
            table.Load(reader);
        }
        return table;
    }
}

这样,您将只返回所需的数据。

如果你喜欢调用这个方法总是传递productId,你根本不需要返回DataTable,你可以返回结果:

public int GetProductQuantitySummary(int productId)
{
    using (var cn = new SqlConnection("..."))
    using (var cm = new SqlCommand("", cn))
    {
        cn.Open();
        cm.CommandText = @"
            SELECT   SUM(qty) SumQty
            FROM     Products
            WHERE    product_id = @product_id";
        cm.Parameters.AddWithValue("@product_id", productId);

        return cm.ExecuteScalar() as int? ?? 0;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2015-05-18
    • 2010-10-15
    • 1970-01-01
    • 2011-08-08
    相关资源
    最近更新 更多