朋友们先回答两个问题:
select SQL_CALC_FOUND_ROWS * from product where 1=1 order by pid asc limit 0,15
select found_rows() as ct
在mysql5命令行里面执行这两句,ok不ok?
ok
Java代码:
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
CachedRowSetImpl record = new CachedRowSetImpl();
record.populate(rs);
rs = stmt.executeQuery("select found_rows() as count");
int totalRecord = 0;
if(rs.next())
{
totalRecord = rs.getInt("count");
}
我们在Java代码里面这样写ok不ok?
不一定,取决于用哪个版本的mysql-connector-J。下图是我针对目前流行的mysql-connector-J各版本的支持情况的测试:
结论:目前大部分mysql-connector-J在上述编程方法情况下都有问题。难道必须要回退到3.0.10 版本?
我当然不甘心。
既然怀疑mysql-connector-J的代码有问题,那就把源码下载下来看看。
经过仔细检查,mysql-connector-J里面就没有对found_rows() 做处理。
到此陷入僵局,该从哪入手?
打开mysql 查询日志(mysql.ini配置[mysqld] log=XX.log)
111106 15:25:07 2 Connect ouyangshixiong@localhost on ouyangshixiong
2 Query select SQL_CALC_FOUND_ROWS * from product where 1=1 order by pid asc limit 0,15
2 Query SHOW CHARACTER SET
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query SHOW FULL COLUMNS FROM `ouyangshixiong`.`product`
2 Query select found_rows() as ct
哇塞,两次查询哪来的这么多query日志?
想一下,record.populate(rs);这条语句非常可疑了。我没能下载到CachedRowSetImpl源码,还好有些网站提供源代码浏览。(哪位朋友下到源码麻烦发给我一下13062981@qq.com ,或者告诉我官方下载方法,谢谢~)
读CachedRowSetImpl源码发现populate方法调用了initMetaData方法,它又调用了conn.getMetaData()。细心的朋友可能发现了,哪来的connection呢,我们的参数只传了ResultSet!
获取的方法在这里:rs.getStatement().getConnection()。够bt,够隐蔽吧!
到此我们可以大胆猜测一下bug的来龙去脉:
jdk程序员为了实现取Meta信息的功能,在CachedRowSetImpl默认发起了大量请求,没有通知外部调用者,甚至没有对found_rows() 必须要跟在select SQL_CALC_FOUND_ROWS 后面做兼容处理。他可能认为这应该由mysql程序员保证正确性。
mysql-connector-J的程序员没有仔细测试CachedRowSetImpl代码,且在新版本mysql里默认打开取Meta功能。
这里至少有2个问题:
1. 性能可能受影响,大量的SHOW FULL COLUMNS (我没有在生产环境下评估过)
2. SQL_CALC_FOUND_ROWS & found_rows()的失去原子性,产生正确性问题。
我继续来找解决方法:
http://bugs.mysql.com/bug.php?id=43571 看看这个bug反馈。是不是跟本文碰到的情况很相识?
mysql程序员给出解决方案:
http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html
good!
我们修改连接配置:jdbc:mysql://localhost:3306/ouyangshixiong?user=ouyangshixiong&password=12345163&useUnicode=true&characterEncoding=UTF8&useDynamicCharsetInfo=false
设置useDynamicCharsetInfo参数为关闭。好了,在mysql5.1下我就可以自由使用 SQL_CALC_FOUND_ROWS found_rows() 了。
总结:开发环境调试日志要全开;对mysql要多研究,各种参数都要了解;多读点jdk源代码没坏处;碰到问题要耐心,认真。
分享到:
相关推荐
那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:代码如下mysql> SELECT SQL_
mysql的SQL_CALC_FOUND_ROWS 使用 获取查询的行数 在很多分页的程序中都这样写: 代码如下 SELECT COUNT(*) from `table` WHERE ……; 查出符合条件的记录总数 代码如下 SELECT * FROM `table` WHERE …… limit M,N;...
讲述了__IO_CALC_ADDRESS_NATIVE的作用,
多态信息含量(PIC polymorphism information content):在连锁分析中一个遗传标记多态性可提供的信息量的度量。它是一个亲本为杂合子,另一亲本为不同基因型的概率。现常用来衡量座位多态性高低的程度。
朱文泉博士NPP计算模型,放入ENVI扩展文件夹后使用,方便实用,如有侵权,请联系删除。
行业教育软件-学习软件-软件下载_学习软件_电脑学习_Calc Pilot 1.50免费下载.zip
ads_order_calc_tact.sh
行业教育软件-学习软件-软件下载_学习软件_电脑学习_Calc Pilot 1.50免费下载 (1).zip
Modbus RTU CRC-16校验码生成器 CRC_Calc v0.3 这是最新版,多达21种CRC生成公式。体积小巧,免安装,是程序员工程师必备的神器,巴拉巴拉
Modbus RTU CRC-16校验码生成器CRC_Calc v0.2
另外一种是使用SQL_CALC_FOUND_ROWS 复制代码 代码如下:SELECT SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10; SELECT FOUND_ROWS(); 第二种方式调用SQL_CALC_FOUND_ROWS之后会将WHERE语句查询的行数...
在很早以前(记得大概在 2013 年的样子吧)分享了自己写的一个 SPWM 工具与一些相关技术资料,这期间收到了许多网友的信息,也结交了不少的网友。总体来说本 SPWM 工具使用起来还是比较简单方便的,之前在几个大的...
SP_M_WARN_CREDIT_CALC_SNS.prc
Calculate Hedge Trading Draw Down
压缩包内包含CRC_Calc和CheckOut两种全面的CRC计算器,涵盖几乎所有类型的CRC算法的计算,方便快捷,
MYSQL的关键词 : SQL_CALC_FOUND_ROWS 查看手册后发现此关键词的作用是在查询时统计满足过滤条件后的结果的总数(不受 Limit 的限制) 例如: 代码如下: SELECT SQL_CALC_FOUND_ROWS tid FROM cdb_threads WHERE fid...
1_02_calc_problems.ipynb
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
有的ANSYS12安装包中的MAGNiTUDE中ap121_calc不能用,笔者上传到此,希望能帮到大家
黑洞数值计算的程序,采用最新算法,有效计算每分钟可达200个数值,参考价值不错。