我要求 Java + JPA / Hibernate + Mysql 的具体案例,但我认为您可以将这个问题应用于大量语言。
有时我必须对数据库执行查询以获取某些实体,例如员工。假设您需要一些特定的员工(名字以“John”为名的员工),您是希望通过查询返回这组确切的员工,还是希望搜索所有员工,然后使用编程语言来检索你感兴趣的那些?为什么(轻松,效率)?哪个(通常)更有效?
根据表的大小,一种方法是否比另一种更好?
考虑:
- 两种情况下的复杂性和可重用性相同。
我要求 Java + JPA / Hibernate + Mysql 的具体案例,但我认为您可以将这个问题应用于大量语言。
有时我必须对数据库执行查询以获取某些实体,例如员工。假设您需要一些特定的员工(名字以“John”为名的员工),您是希望通过查询返回这组确切的员工,还是希望搜索所有员工,然后使用编程语言来检索你感兴趣的那些?为什么(轻松,效率)?哪个(通常)更有效?
根据表的大小,一种方法是否比另一种更好?
考虑:
始终对数据库进行查询。如果您不这样做,则必须将更多数据复制到客户端,并且还编写数据库以有效过滤数据,几乎可以肯定比您的代码更有效。
我能想到的唯一例外是,如果过滤条件在计算上很复杂,并且您可以将计算分散到比数据库更多的 CPU 能力上。
在我有一个数据库的情况下,服务器比客户端拥有更多的 CPU 能力,所以除非过载,否则对于相同数量的代码只会更快地运行查询。
此外,您必须编写更少的代码来使用 Hibernates 查询语言对数据库进行查询,而不必编写代码来操作客户端上的数据。Hibernate 查询还将利用配置中的任何客户端缓存,而无需编写更多代码。
一般来说,我会让数据库做数据库擅长的事情。过滤数据是数据库真正擅长的事情,所以最好留在那里。
也就是说,在某些情况下,您可能只想获取所有这些并在代码中进行过滤。我能想到的一种方法是,如果行数相对较少并且您计划将它们缓存在您的应用程序中。在这种情况下,您只需查找所有行,缓存它们,然后根据缓存中的内容进行后续过滤。
编程中经常使用一个通用技巧——用内存来加速操作。如果您有很多员工,并且您要逐个查询其中的很大一部分(比如,75% 的员工将一次或一次被查询),然后查询所有内容,缓存它(非常重要!),并完成在内存中的查找。下次查询时,跳过 RDBMS 的行程,直接进入缓存,并进行快速查找:与内存中的哈希查找相比,到数据库的往返非常昂贵。
另一方面,如果您正在访问一小部分员工,您应该只查询一个员工:从 RDBMS 到您的程序的数据传输需要大量时间、大量网络带宽、大量内存,以及 RDBMS 端的大量内存。查询大量行以丢弃除一行之外的所有行是没有意义的。
这是情景。我认为总的来说,最好使用 sql 来获取确切的结果集。
加载所有实体然后以编程方式搜索的问题是您必须加载所有实体,这可能会占用大量内存。此外,您还必须搜索所有实体。当您可以利用您的 RDBMS 并获得您想要的确切结果时,为什么要这样做。换句话说,当您可以让您的 RDBMS 为您完成工作时,为什么要加载可能使用过多内存的大型数据集,然后对其进行处理?
另一方面,如果你知道你的数据集的大小不是太大,你可以将它加载到内存中然后查询它——这样做的好处是你不需要去 RDBMS,这可能会也可能不会需要通过您的网络,具体取决于您的系统架构。
但是,即使这样,您也可以使用各种缓存实用程序来缓存常见的查询结果,这消除了自己缓存数据的优势。
请记住,您的方法应该随着时间的推移而扩展。随着时间的推移,可能是一个小的数据集可能会在以后变成一个巨大的数据集。我们遇到了一个程序员的问题,他编写了应用程序来查询整个表,然后对其进行操作。当只有 100 行带有两个子选择时,该方法运行良好,但随着数据多年来的增长,性能问题变得明显。甚至插入日期过滤器以仅查询过去 365 天,可以帮助您的应用程序更好地扩展。
-- 如果您正在寻找特定于休眠的答案,请查看@Mark 的答案
给定员工示例 - 假设员工数量可以随时间扩展,最好使用一种方法来查询数据库以获取确切数据。但是,如果您正在考虑像 Department(例如)这样的数据,其中数据快速增长的机会较少,那么查询所有这些数据并将其保存在内存中很有用 - 这样您就不必访问外部资源(数据库)每次,这可能是昂贵的。
所以一般参数是这些,
从某种意义上说,当数据不会频繁扩展并且数据不是关键任务并且数据量可以在应用程序服务器的内存中进行管理并且经常使用时 - 如果需要,可以将它们全部带入并以编程方式过滤它们。
否则仅获取特定数据。
什么更好:在家中储存大量食物或一点一点购买?当你经常旅行?只是在举办派对时?这取决于,不是吗?同样,最好的方法是性能优化。这涉及很多变数。艺术是在设计解决方案时防止自己陷入困境,并在您知道真正的瓶颈时进行优化。一个很好的起点在这里:en.wikipedia.org/wiki/Performance_tuning 一个想法可能或多或少普遍有用:很好地封装您的数据访问。