MySQL 5.7.20 - SELECT FOUND_ROWS() 返回错误结果

标签 mysql jdbc

使用 Spring JdbcTemplate 通过 JDBC 进行查询时,我在 MySQL 5.7.20 中遇到了一个奇怪的问题。问题是 SELECT FOUND_ROWS() 并不总是返回正确的结果,有时似乎返回以前版本的查询执行的结果。例如:

Query 1 - FOUND_ROWS = 0 - LIMIT query = 0
Query 2 - FOUND_ROWS = 0 - LIMIT query = 2
Query 3 - FOUND_ROWS = 2 - LIMIT query = 2
Query 4 - FOUND_ROWS = 2 - LIMIT query = 0

这是查询:

SELECT SQL_CALC_FOUND_ROWS questions.id, questions.question, 
   MATCH(questions.question) AGAINST('echo') as tscore,
   MATCH(answers.answer) AGAINST('echo') as ascore,
   MATCH(votes.comment) AGAINST('echo') as cscore
FROM questions 
LEFT JOIN answers ON questions.id = answers.questionId 
LEFT JOIN votes ON answers.id = votes.answerId
LEFT JOIN users ON questions.userId = users.id
WHERE 
  MATCH(questions.question) AGAINST('echo')
  OR MATCH(answers.answer) AGAINST('echo')
  OR MATCH(votes.comment) AGAINST('echo')
GROUP BY questions.question
ORDER BY (tscore + ascore + cscore) DESC
LIMIT 0,5;

紧接着调用:

SELECT FOUND_ROWS();

我最初认为这可能与 JdbcTemplate 连接池以及为调用 SELECT FOUND_ROWS() 分配不同的连接有关,但是查看代码,根据调用线程分配回相同的连接,所以我有排除了这种可能性。

如果您能提供任何帮助,我们将不胜感激。

最佳答案

我认为您可能对SQL_CALC_FOUND_ROWS的功能有误解。来自MySQL documentation :

SELECT SQL_CALC_FOUND_ROWS *
FROM tbl_name
WHERE id > 100
LIMIT 10;

SELECT FOUND_ROWS();

使用 FOUND_ROWS() 进行的第二个查询返回如果未使用 LIMIT本应返回的记录数。

所以这是对结果的正确解释:

Query 1 - returns 0 - would have returned 0 without LIMIT
Query 2 - returns 0 - would have returned 2 without LIMIT
Query 3 - returns 2 - would have returned 2 without LIMIT
Query 4 - returns 2 - would have returned 0 without LIMIT **

** 最后的结果似乎很可疑,因为删除 LIMIT 不应减少结果集的大小。

编辑:

如果查询 4 ​​结果实际上是真实的,那么该查询的 FOUND_ROWS 结果可能确实对应于另一个查询。您忽略了连接可能是问题的可能性,但实际上您可能做得太快了。最有可能的是,您的 Spring 应用程序被配置为维护连接池,即与数据库的固定数量的连接。但问题是,任何线程都可能使用它们,因此不能保证有人可以在您更改调用 FOUND_ROWS 之前介入并运行另一个查询。

这里的一个可能的修复方法是在单个事务中运行两个查询,即LIMITFOUND_ROWS查询。这将保证两个查询都以原子方式执行。

关于MySQL 5.7.20 - SELECT FOUND_ROWS() 返回错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48850489/

相关文章:

json - JPA (EclipseLink) 自定义类型是否可行?

mysql - 如何在 INSERT IGNORE 语句中获取被忽略行的 PK

spring - JDBCTemplate setQueryTimeout 特定于每个查询,即查询级别

Java preparedStatement设置

php - 在 Mysql/PHP 中删除基于浮点列的行?

php - 如何在不访问 Laravel (PHP) 中的 Web 的情况下更新表格?

mysql - 在查询中使用 * 时为 `You have an error in your SQL syntax;`

mysql - 突出显示表 html 中的一行,该行的值超过平均值

php - MySQL数据库性能问题。 (MyISAM)

java - 无法建立 JDBC 连接 [jdbc :postgres://localhost:5432/hibernatedb]