简体   繁体   English

Java MySQL jdbc与Hibernate一起执行Select查询

[英]Java MySQL jdbc vs Hibernate on implementation of Select queries

sorry for the vague question, as I do not know how to write it in proper sentence, if any of you wish to edit it to something more meaningful please go ahead. 对于这个模糊的问题,我们深表歉意,因为我不知道如何用恰当的句子来写它,如果您想对它进行更有意义的编辑,请继续。

I actually wanted to ask, when we do something like this: 我实际上想问,什么时候我们做这样的事情:

Select * from TableWithBillionRecords Limit 1000000

using either result set: 使用任一结果集:

PreparedStatement.executeQuery()

or Hibernate: 或休眠:

getCurrentSession().createQuery(query).list()

Once the line is executed, does it means the web server is actually pulling out the whole 1 million rows from my database server? 一旦执行了该行,这是否意味着Web服务器实际上从我的数据库服务器中提取了整整100万行? Or is there some streaming logic lies behind the interface? 还是接口背后隐藏着一些流逻辑?

Thanks for the information as it helps me in deciding whether or not I should break it to multiple queries selecting chunk by chunk or if it is actually alright to just select it one whole bunch. 感谢您提供的信息,因为它可以帮助我确定是否应该将其拆分为多个查询,逐个选择一个块,或者实际上只选择一整堆都可以。

Thanks again guys. 再次感谢你们。

Most of the JDBC drivers' default fetch size is 10. 大多数JDBC驱动程序的默认访存大小为10。

In normal JDBC programming if you want to retrieve 1000 rows it requires 100 network round trips between your application and database server to transfer all data. 在普通的JDBC编程中,如果要检索1000行,则需要在应用程序和数据库服务器之间进行100次网络往返传输所有数据。 Definitely this will impact your application response time. 无疑,这会影响您的应用程序响应时间。

The reason is JDBC drivers are designed to fetch small number of rows from database to avoid any out of memory issues. 原因是JDBC驱动程序旨在从数据库中获取少量行,以避免出现内存不足的问题。

For example if your query retrieves 1 million rows, the JVM heap memory may not be good enough to hold that large amount of data hence JDBC drivers are designed to retrieve small number (10 rows) of rows at a time that way it can support any number of rows as long as you have better design to handle large row set at your application coding. 例如,如果您的查询检索到100万行,则JVM堆内存可能不足以容纳大量数据,因此JDBC驱动程序被设计为一次检索少量(10行)的行,从而可以支持任意数量的行。只要您有更好的设计来处理应用程序编码中的大行集,行数就可以了。

If you configure fetch size as 100, number of network trips to database will become 10. This will dramatically improve performance of your application. 如果将提取大小配置为100,则到数据库的网络旅行次数将变为10。这将大大提高应用程序的性能。

Important note to consider when tuning fetch size: 调整提取大小时要考虑的重要注意事项:

  1. Make sure your JDBC driver supports configuring fetch size. 确保您的JDBC驱动程序支持配置提取大小。
  2. The fetch size should be based on your JVM heap memory setting. 提取大小应基于您的JVM堆内存设置。 Since JVM heap size varies between different environment, don't hard-code fetch size keep it as configurable parameters. 由于JVM堆大小在不同的环境之间会有所不同,因此请不要对获取大小进行硬编码,以使其保持为可配置参数。
  3. If your fetch size is large, you might encounter out of memory issue. 如果获取大小很大,则可能会遇到内存不足的问题。 For example a less number of column tables might support large rows fetch size than more number of columns. 例如,较少数量的列表可能比较大数量的列支持大行读取大小。
  4. You can set fetch size based certain datatype like blob, image, etc. We follow certain naming convention for columns for example all image and blob column will have suffix “Blob”. 您可以基于某些数据类型(例如blob,image等)设置获取大小。我们对列遵循某些命名约定,例如,所有image和blob列的后缀均为“ Blob”。 I set high fetch size if the query doesn't contain “Blob” word otherwise set low fetch size. 如果查询中不包含“ Blob”字样,则设置较高的提取大小,否则设置较低的提取大小。

Refer: http://webmoli.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/ 请参阅: http//webmoli.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/

Hibernate fetches results eagerly by default, because that's what most interactions with databases tend to be like: Fetch a couple of records, display them, possibly modify them, store them again. 默认情况下, Hibernate会急切地获取结果,因为与数据库的大多数交互操作通常都是这样:提取几条记录,显示它们,可能修改它们,然后再次存储。

Fetching millions of rows is an entirely different use-case mostly applied when: 提取数百万行是一个完全不同的用例,主要用于以下情况:

  • Doing ETL ETL
  • Doing analytics (although you should probably do analytics in the database, not in the client) 做分析(尽管您可能应该在数据库中而不是在客户端中进行分析)

Specifically, Hibernate doesn't offer any way to keep a lazy cursor in the database and scroll it lazily like JDBC or some other ORMs. 具体来说, Hibernate没有提供任何方法来像在JDBC或某些其他ORM中那样在数据库中保留惰性游标并进行惰性滚动。 But it doesn't need to. 但这不是必须的。 You can always resort to plain JDBC in Hibernate projects. 您始终可以在Hibernate项目中求助于纯JDBC。

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

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