慢 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 查询
我最近启动了一个通过 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 查询