【问题标题】:C# ODBC: Improving performance for thousands of select queriesC# ODBC:提高数千个选择查询的性能
【发布时间】:2020-08-29 14:40:07
【问题描述】:

我使用的数据库是 Progress OpenEdge。在我的程序中,我获取了数千个序列号并在数据库中查询与它们相关的信息。

基本上,下面的这段代码需要大约 6000 个序列号,并为每个序列号创建一个选择查询,并返回一个包含字符串的列表。

/// <summary>
/// Builds a list of queries for each serial number in param<c>sn</c>
/// </summary>
/// <param name="sn">A list of valid serial numbers</param>
/// <returns>A list of strings where each string is a sql query for a serial number's information</returns>
private static List<string> BuildQuery(List<string> sn)
   {
      return sn.Select(s => "SELECT a.\"Date-Created\", a.\"date-produced\", a.employee, " +
                            "a.\"Item-Code\", a.\"job-number\", a.\"station-produced\", " +
                            "a.\"shift-produced\", a.\"Serial-Number\", a.\"parent-serial\", " +
                            "a.\"gross-wgt\", a.\"qty-base\", a.\"resin-wgt\", " +
                            "a.\"tare-wgt\", a.\"Integer-1\", a.\"unit-number\" FROM " +
                            $"CUSTOM10.PUB.\"imsngsnt\" a WHERE a.\"Serial-Number\" = '{s}'").ToList();
   }

然后我循环调用这个函数的列表 ~6000 次。

/// <summary>
/// Makes a query to the given connection <c>conn</c> and query <c>sql</c> and returns the information for the serial number <c>sn</c>
/// </summary>
/// <param name="conn">Connection to SNT database</param>
/// <param name="sql">SQL query</param>
/// <param name="sn">The serial number the query pertains to</param>
/// <returns><c>SerialInformation</c> containing the information for Serial number <c>sn</c></returns>
private static SerialInformation MakeQuery(OdbcConnection conn, string sql, string sn)
   {
       var set = new DataSet();
       // Perform all queries
       var adapter = new OdbcDataAdapter(sql, conn);

       adapter.Fill(set);
       if (set.Tables[0].Rows.Count == 0) return null;
       var info = ConvertDataSet(set);
       // Add starting serial number to info
       info.StartingSerial = sn;
       return info;
    }

我知道这非常低效,我想知道如何使用 .NET System.Data.ODBC 更快地进行这些查询。

【问题讨论】:

  • 嗯,一个明显的瓶颈是,您分别为每个序列号执行此操作。现在将所有 6000 个序列号放在一个查询中("WHERE a.\"Serial-Number\" IN ('{sn1}', '{sn2}', [...], '{sn6000}')")可能行不通,但是您可以尝试 500 个甚至 100 个批次,无论查询长度如何。假设这个数据库允许“IN”子句。 -- 否则,这个表/视图中有多少行?也许获取一切然后在内存中工作会更容易......
  • 我敢打赌那会更好。提取所有信息可能是不行的。据我所知,有成千上万行。

标签: c# sql .net-core odbc openedge


【解决方案1】:

如果允许在数据库中创建表,则创建表:

CREATE TABLE search_serial_numbers (
  "Serial-Number" INTEGER 
  -- or is it VARCHAR(n)? 
  -- EXACT SAME TYPE AS "Serial-Number" in the 
  -- CUSTOM10.PUB."imsngsnt" table!
);

然后,在一次 SQLExecute() 调用中将 ~6000 行的数组插入到search_serial_numbers 表中。

然后,去 - (我会用普通的 SQL 来写,你可以根据需要从 C# 中连接字符串):

SELECT 
  a."Date-Created"
, a."date-produced"
, a.employee
, a."Item-Code"
, a."job-number"
, a."station-produced"
, a."shift-produced"
, a."Serial-Number"
, a."parent-serial"
, a."gross-wgt"
, a."qty-base"
, a."resin-wgt"
, a."tare-wgt"
, a."Integer-1"
, a."unit-number"
FROM CUSTOM10.PUB."imsngsnt" a 
INNER JOIN search_serial_number b
on a."Serial-Number" = b."Serial-Number"
;

【讨论】:

    猜你喜欢
    • 2019-09-06
    • 2016-01-09
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2013-01-16
    相关资源
    最近更新 更多