7

我的应用程序在 Hibernate 中使用 JPA,我看到 hibernate 在我的日志文件中生成了一些有趣的 SQL 查询,其中包含很多连接。该应用程序现在没有很多用户,我担心当数据库规模增长时,hibernate 生成的一些查询会导致问题。

我已经通过 EXPLAIN 命令运行了一些由 hibernate 生成的 sql 查询,以查看生成的查询计划。

  1. EXPLAIN 的输出是否取决于数据库的大小?当我的数据库变大时,查询计划器会为相同的 SQL 查询生成不同的计划吗?

  2. 在开发/部署周期的哪个阶段,我应该查看 hibernate 生成的 sql 查询的 SQL 查询计划?什么时候是使用 EXPLAIN 的合适时机。

  3. 当数据库如此之小以至于无论看起来多么复杂的每个查询都在 0.5 秒内运行时,explain 的输出如何用于确定查询是否会成为问题?

我使用 Postgres 9.1 作为我的应用程序的数据库,但我对上述问题的一般答案很感兴趣。

4

2 回答 2

5

实际上,@ams 你的评论是对的——用少量数据解释通常是没有意义的。

如果一个表只有 10 行,那么它很可能都在一页中,并且读取一行的成本(大致)与读取所有 10 行的成本相同。首先访问索引然后获取页面将比仅读取大量更昂贵并忽略你不想要的。PostgreSQL 的规划器已经为索引读取、表读取、磁盘访问与缓存访问、排序等配置了成本。它根据表的(近似)大小和其中的值分布来调整这些成本。它不做的(截至待定的 9.2 版本)是考虑跨列或跨表相关性。它也不提供手动提示,让您覆盖计划者的选择(与 MS-SQL 或 Oracle 不同)。

每个 RDBMS 的规划器都有不同的优势和劣势,但我认为可以公平地说 MySQL 是最弱的(尤其是在旧版本中)。

所以 - 如果您想知道您的系统在 100 个并发用户和数十亿行的情况下将如何执行,您将需要生成测试数据并加载其中相当大的一部分。更糟糕的是,您还希望拥有大致相同的值分布。如果大多数客户有大约 10 张发票,但少数有 1000 张发票,那么这就是您的测试数据需要反映的内容。如果您需要跨多个 RDBMS 保持性能,请在所有 RDBMS 上重复测试。

当然,这与系统的整体性能是分开的,这取决于服务器的大小和功能与其所需的负载。一个系统可以应对负载的稳定增长,然后突然你会看到性能迅速下降,因为超过了缓存大小等等。

高温高压

于 2012-09-07T08:37:57.860 回答
4

1 EXPLAIN 的输出是否取决于数据库的大小?当我的数据库变大时,查询计划器会为相同的 SQL 查询生成不同的计划吗?

这完全取决于您的数据和有关数据的统计信息。当有人忘记分析或关闭 auto_vacuum(包括分析)时,由于缺乏统计信息,会出现许多性能问题。

2 在开发/部署周期的哪个阶段,我应该查看由休眠生成的 sql 查询的 SQL 查询计划?什么时候是使用 EXPLAIN 的合适时机。

Hibernate 有向数据库发送大量查询的习惯,即使对于简单的连接也是如此。打开你的查询日志,并留意那个。稍后,您可以对日志中的所有查询运行自动解释。

3 当数据库如此之小以至于无论看起来多么复杂的每个查询都在 0.5 秒内运行时,如何使用 explain 的输出来确定查询是否会成为问题?

不,因为这完全取决于数据。当 95% 的用户是男性时,搜索男性时不会使用性别索引。当你在寻找一个女人时,这个索引是有意义的并且会被使用。对性别 = 女性的记录的功能索引甚至更好:索引永远不会从索引中受益的东西是没有用的,并且索引会小得多。

您可以做的唯一一件事是预测索引的使用情况,使用set enable_seqscan = off;它进行测试将表明可以使用某些索引,但仅此而已。

于 2012-09-07T09:28:17.720 回答