繁体   English   中英

多个准备语句或批处理

[英]Multiple Prepared Statements or a Batch

我的问题很简单,在标题中。 谷歌和堆栈溢出给了我什么,所以我认为是时候提问了。

我目前正在为用户注册我的网站时进行SQL查询。 我总是只使用预处理语句b / c可调用语句中的额外编码,并且常规语句的性能命中都是关闭的。 然而,这个查询让我想到了我之前的一个大小适合所有(预备语句)方式的可能替代方案。

此查询共有4次往返数据库。 步骤是

  1. 将用户插入数据库,在结果集中获取生成的密钥(他们的用户ID)。
  2. 获取用户ID并在专辑表中插入一行。 取回生成的密钥(相册ID)
  3. 获取相册ID并在images表中插入一行。 获取生成的密钥(图像ID)
  4. 获取图像ID并使用图像ID更新用户表当前默认列

旁白:对于那些对我在插入后获取密钥的方式感兴趣的人,使用Statement.RETURN_GENERATED_KEYS ,你可以在这里阅读一篇很棒的文章 - IBM文章

所以无论如何我想知道使用4次往返(但可缓存)准备好的语句是否合适,或者我是否应该使用批量(但不可缓存)语句?

JDBC批处理语句允许您在插入或更新的行之间没有数据依赖性的情况下减少往返次数。 您的方案在这种情况下失败,因为更改依赖于彼此的数据:语句2到4必须从先前的语句1到3中获取ID。

另一方面,四次往返肯定不是最理想的。 这就是像您这样的场景调用存储过程的原因:您可以将所有这些逻辑放入create_user_proc ,并将用户ID返回给调用者。 从1到4的所有插入都会在SQL代码中发生,让您可以在SQL中管理ID依赖项。 您可以在单个往返中调用此存储过程,这肯定更快,特别是如果您每分钟处理多个用户注册。

我建议写一个存储过程执行所有这四个操作并立即从应用程序(到存储过程)传递所有必需的参数,并在存储过程中,您可以获得生成的结果集键

为了提高性能并减少数据库往返,我同意dasblinkenlight和ajduke - 存储过程将实现这一目标。

但是,这真的是您应用程序中的性能瓶颈吗?

  • 用户在您的网站上注册的频率如何?
  • 将此与从这些表中读取信息的频率(每页访问一次?)进行比较

如果这些表中的信息读取的次数比通过新注册写入的次数高出数千倍,则可能不值得采用存储过程方法。

为什么您可能不想使用存储过程并坚持使用准备好的语句:

  • 不像使用预准备语句那样可移植(每个数据库使用不同的语法/语言,一些更简单的数据库甚至不支持它们)
  • 不能与JPA *等ORM解决方案一起使用 - 你提到直接使用PreparedStatements,所以这可能不适用于你,至少现在不适用,但如果你想在将来使用ORM,它可能会限制你以后

* JPA 2.1实际上可能支持存储过程 ,但截至编写时尚未发布。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM