草庐IT

c# - SQLite/C# 连接池和准备语句混淆

coder 2023-07-10 原文

我一直在花一些时间阅读有关数据库和 SQLite 的不同最佳实践。在阅读时,我发现我做了很多不应该做的事情,当我试图解决这些问题时,我在考虑使用 SQLite 及其 ADO 实现的一些更精细的细节时感到困惑。

我的困惑特别源于准备好的语句和连接池。

阅读时http://msdn.microsoft.com/en-us/library/ms971481.aspx我发现应该只为事务打开连接。事务完成后,应关闭连接。我不太清楚为什么会这样,但我一直在假设作者比我更了解。我知道当连接关闭时并不意味着它实际上已经被关闭。它只是意味着它已被放回池中。

现在为了改进我的查询和插入,我阅读了有关使用准备好的语句的内容。 In SQLite, do prepared statements really improve performance?http://petesbloggerama.blogspot.com/2007/02/sqlite-adonet-prepared-statements.html两者似乎都表明,在执行将多次执行的查询时,准备好的语句是可行的方法。我还读到准备好的语句是特定于连接的,一旦连接关闭,准备好的语句就会丢失。

我的困惑是这样的。如果我正在打开和关闭我的连接(这可能意味着也可能不意味着连接由于线程池而被关闭)那么我真正从准备好的语句中获得了多少用处?我可以理解,如果我需要在单个事务中保存 1000 个对象,则准备好的语句可以提供很大帮助。但是我不认为我会看到在事务中保存单个对象有什么好处,因为一旦我关闭连接,从第一个对象生成的准备好的语句现在就会丢失。这是真的吗?

我认为准备好的语句链接到我的 SQLiteCommand 对象的范围这一事实使我更加困惑。

如果我创建了一个代表我将经常执行的查询的 SQLiteCommand,我是否需要将该 SQLiteCommand 保留在内存中以使准备好的语句保持事件状态?

如果我使用相同的 SQLite 语句创建一个新的 SQLiteCommand,它是否会识别出新的 SQLiteCommand 与之前的 SQLiteCommand 相同,从而有一个可以使用的准备好的语句?

如果我在内存中保留一个 SQLiteCommand 并在我为不同的事务打开和关闭连接时更改它的参数和连接,我是否实质上让准备好的语句在不同的连接之间保持事件状态?

此时我很可能想多了,但我希望你能帮助我更好地理解这些东西是如何相互作用的,这样我才能从中获得最大的好处。

最佳答案

记住连接池和准备(编译)语句都只是有其局限性的工具,没有一种方法可以同样适用于所有可能的情况。考虑到这一点,让我们记住什么时候可能想要使用连接池和准备好的语句。

使用连接池的可能原因

连接池在连接开销很大时很有用,例如:

  • 建立连接(到 SQL Server 或 Oracle 数据库的网络连接)需要大量时间,“缓存”打开的连接以尝试提高系统性能是有益的。
  • 连接在一个应用程序(来自服务多个并发请求的 Web 应用程序的连接)或应用程序之间是有限和共享的,因此必须尽快释放它们以让其他客户端继续。

使用准备好的语句的可能原因

准备好的语句只是为了通过减少解析时间来提高可重用查询的性能。

SQLite:最佳选择是什么?

答案取决于您的应用要求。就个人而言,我不确定 SQLite 连接池是否一定是一个不错的选择。如果您的应用程序是单线程的,那么最好使用与 SQLite 数据库的单一永久连接,这可能比池化快得多,并且也允许您使用准备好的语句。这与 SQL Server 不同,后者的连接池是一个非常合理的默认值。

如果性能很重要,您绝对应该分析应用程序以查看 SQLite 连接池是否对您的方案有益。

具体问题

大部分答案都与当前的 System.Data.SQLite 提供程序有关 source .

If I am opening and closing my connection (which may or may not mean the connection is being closed due to the thread pool) then how much use am I really getting from a prepared statement?

通常,您应该将来自池的连接视为新连接,即您不应期望从先前准备的语句中获得任何好处。除非您同时保留命令和连接,否则该语句将“重新准备”。

However I don't believe I would see a benefit from saving a single object in a transaction because once I close the connection the prepared statement that was generated from the first object is now lost. Is this a true statement?

这是一个真实的陈述。

If I create a SQLiteCommand that represents a query that I will be executing often do I need to keep that SQLiteCommand in memory for the prepared statement to stay active?

是的,你需要保留它。 SQLiteCommand 持有对准备好的语句的引用。

If I create a new SQLiteCommand with the same SQLite statement is it recognized that the new SQLiteCommand is the same as the previous and thus has a prepared statement that can be used?

我认为它不受支持。

If I keep a SQLiteCommand in memory and change it's parameters and connection as I open and close the connection for different transactions am I essentially keeping a prepared statement alive between different connections?

如果您更改SQLiteCommand 的连接,语句将“重新准备”。

关于c# - SQLite/C# 连接池和准备语句混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10703814/

有关c# - SQLite/C# 连接池和准备语句混淆的更多相关文章

  1. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  2. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  8. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  9. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  10. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

随机推荐