Firebird on C#:FbCommand.ExecuteReader()性能

时间:2014-02-22 06:51:40

标签: c# performance firebird

我正在使用C#(sharpdevelop)来访问firebird 2.5服务器。这非常有效。但是,我遇到了性能问题。 我有两个表,成员和交易存储谁买什么时候。要查看一段时间没有活动的人,我运行以下复合查询:

SELECT * FROM members M 
WHERE exists (select 1 from transactions WHERE taDateTime >= '30.06.2013' and Memberid = M.ID)

因此,Members-table在字段ID上有一个主索引,而表事务在taDateTime和MemberID上都有indeces。

myConnection = new FbConnection(myConnectionString);
Connection.Open();

// property of a helper class, uses myConnection
// Then when I press the Search button:
// create the sql command, because the cut-off date is passed as a dbParam
IDbCommand aCmd = new FbCommand(sql, Connection);
IDataReader aReader = aCmd.ExecuteReader();

我现在在会员中有几个10'000个条目,在交易中有几个100'000个条目。如果我在flamerobin中运行此查询,则运行大约需要2.6秒。这不是惊心动魄,而是足够的。但是,如果我在C#中运行此查询,我只需要3分钟即可从通话中返回   FbCommand.ExecuteReader(SQL)。 我还没有对结果集进行循环,这纯粹是对ExecuteReader()的调用。这需要做什么需要这么长时间?

我尝试过其他一些事情,因为通过添加ROWSFIRST子句来限制结果数量,两者都没有效果。所以重要的不是结果的数量。 我试图将调用拆分为2个查询:首先找到DISTINCT(Transaction.MemberID),然后找到适合的成员,但是有太多的ID可以合理地传入第二个查询。 我甚至编写了一个首先找到MemberID的循环,然后为每个结果运行"SELECT * FROM Members where ID = xx",这比单个语句更快。那么什么使ExecuteReader的调用延迟这么长?

请帮助,我真的很茫然。

亲切的问候, 汉纳斯

3 个答案:

答案 0 :(得分:0)

我应该通过评论而不是发布答案来澄清这一点,然而,作为一个新手,我不被要求提供更多信息(即评论)!!!

引用您的行“要查看谁没有一段时间没有激活我运行以下复合查询:”,在我看来,此方案中的正确查询应该是......

SELECT * FROM members M 
where M.ID not in (select distinct memberid from transactions WHERE taDateTime >= '30.06.2013')

您撰写的查询将为您提供活跃的人。此外,它还会加载数据库服务器,处理几个10,000 * 100,000条记录。

如果您确实在某个日期之后找到不活跃的人,那么我给您的查询应该比之前的结果至少快100倍。我很想知道结果,无论如何都请让我知道。感谢。

答案 1 :(得分:0)

我同意@Ravi您的查询本身有一些边缘可能需要一些平滑。我在SQL中做得不够好,无法真正预测幕后发生的事情,但仅仅从我的直觉来看,我说你的陈述对我来说是“可疑的”......

但是那仍然不能单独回答你的问题,否则Flamerobin中的执行时间将与从代码执行时一样糟糕。出于这个原因,我希望你的代码中有些东西是罪魁祸首。如果您可以使用更多代码更新帖子,那就太棒了。

需要考虑的事项:

  • 数据库连接是否已打开?打开连接是非常昂贵的性能。
  • 您是否已激活连接池?重用连接可显着提高性能。
  • 是否有其他资源密集型任务/线程或同时运行? 或者,当您执行该语句时,是否存在对数据库执行的其他读/写访问?可能有几次访问正在等待彼此完成。
  • 您是否将查询结果绑定到了用户界面?这里有数百个潜在的性能瓶颈。
  • 此外,如果您有手头的探查器,请查看执行计划。该声明是否使用指数?或者它是否执行全表扫描(或任何可能发生的奇怪事情)?
  • 你执行前是Prepare()你的命令吗?如果你对数据库多次触发它,这也会给你带来性能提升。

不要忘记,由于.NET代码在JIT编译器执行时需要初始化和分配,因此当第二次运行时,语句可能会运行得更快。试试这个并在第一次查询后第二次(或多次)运行查询。它有所不同吗?

答案 2 :(得分:0)

感谢所有的投入,伙计们!在你的建议中搜索一些关键字让我更详细地分析我的查询,从而发现错误:我的编程“秘密地”在查询结尾处添加了一个“ORDER BY Member.Name”子句,这是罪魁祸首。我一直在调查我的眼皮错过了:)无论如何,我发现了一篇非常有用的文章,用于理解和调整firebird中的查询,并且只能推荐给任何感兴趣的人:http://conferences.embarcadero.com/article/32256。亲切的问候,Hannes