慢 SQL,需要帮助。我应该去记忆吗?

Slow SQL, need assistance. should I go in memory?

我最近启动了一个通过 rest api 公开数据库的应用程序(java 8,spring-boot,hibernate,maven)。我遇到的问题是数据库调用很慢 (3000 ms+) 只是为了得到一行。

我的 table 看起来像这样:(6m 行,210Mb,InnoDB,MySQL)

 Row    |  Type   |   length

 id     |  int    |   10 

 start  |  int    |   10 

 end    |  int    |   10

 rec_id |  int    |   11 - primary key

我的 sql 是:

WHERE start < x AND end > x

但在 Hibernate 约定中:

BlocksEntity findByStartLessThanAndEndGreaterThan(int start, int end)

其中开始和结束是相同的值

我知道这个 BETWEEN(Hibernate 的 > 和 <)可能是一个非常昂贵的操作。 所以,因为这太慢了,我开始在内存中查看 tables,因为:

在这里进行的最佳方式是什么?我真的需要它尽可能地响应,因为它会将内容传送到具有快速超时的网页。我考虑过缓存,但由于我会将结果缓存在用户端点上,因此这里的任何缓存都不会被命中。此外,键 (x) 太独特而无法缓存,很可能不会被命中。

我还阅读了其他 table,但这个是最有问题的。任何帮助和建议将不胜感激。

在 (start, end) 上添加复合索引将解决您的问题。

您的 table 大小很大(600 万行),但查看您没有文本字段的列,所以在我看来,只需添加索引,您的问题就会得到解决,尤其是您没有频繁更新,因此您的索引统计信息将始终是最新的。

我建议将 ehcache 与 hibernate 一起用于缓存实体,但在这种情况下,我认为您不需要它。在其他情况下您可能需要它。

如果索引没有帮助(我认为情况不会如此),则可能是由于索引基数。我不认为你的数据案例只是指向这一点。

要考虑的其他事项:

  • 由于您的数据主要用于读取,我建议您使用 MyISAM 引擎而不是 InnoDB,如果情况并非如此。
  • 最后,我不知道 findByStartLessThanAndEndGreaterThan SQL 输出是什么,但我建议您在休眠配置中将 show_sql 设置为 true 并检查生成的真实 SQL。基于此,如果需要,您可以使用更好的 HQL 查询