`
ouyangshixiong
  • 浏览: 6863 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

mysql-connector-J各版本 SQL_CALC_FOUND_ROWS found_rows() bug探究

 
阅读更多

朋友们先回答两个问题:

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源代码没坏处;碰到问题要耐心,认真。

0
1
分享到:
评论

相关推荐

    mysql SELECT FOUND_ROWS()与COUNT()用法区别1

    当在查询中加入`SQL_CALC_FOUND_ROWS`,MySQL并不会立即返回行数,而是存储这个信息,以便后续的`FOUND_ROWS()`函数使用。这样,你可以得到不考虑`LIMIT`限制的原始行数,而无需再次执行相同的查询。如下所示: ```...

    mysql 含sql_语言教程和 SQL语言艺术两本电子书

    本书详细介绍了如何安装、管理、备份、维护和优化一个MySQL系统。对于每一件服务器操作都提出了多种的解决方案。对于每一种的方法,虽然不一定都是非常实用的方法,读者能通过这些方法,熟悉MySQL的特点和强大的功能...

    mysql found_row()使用详解

    在这个查询中,`SQL_CALC_FOUND_ROWS`告诉MySQL计算不考虑`LIMIT`限制的总行数。然后,你可以单独执行`FOUND_ROWS()`来获取这个计数: ```sql SELECT FOUND_ROWS(); ``` `FOUND_ROWS()`返回的结果将是如果第一个...

    mysql获取group by的总记录行数另类方法

    mysql的SQL_CALC_FOUND_ROWS 使用 获取查询的行数 在很多分页的程序中都这样写: 代码如下 SELECT COUNT(*) from `table` WHERE ……; 查出符合条件的记录总数 代码如下 SELECT * FROM `table` WHERE …… limit M,N;...

    PIC_CALC计算工具

    多态信息含量(PIC polymorphism information content):在连锁分析中一个遗传标记多态性可提供的信息量的度量。它是一个亲本为杂合子,另一亲本为不同基因型的概率。现常用来衡量座位多态性高低的程度。

    __IO_CALC_ADDRESS_NATIVE

    讲述了__IO_CALC_ADDRESS_NATIVE的作用,

    Hedge_DrawDown_Calc_Hedge_DrawDown_Calc_hedge_MT4EA_Drawdown_

    在金融交易领域,尤其是自动化交易(EA)中,"Hedge_DrawDown_Calc_Hedge_DrawDown_Calc_hedge_MT4EA_Drawdown_" 这个标题指的是一个专门用于计算对冲交易(Hedge Trading)期间最大回撤(Drawdown)的工具。...

    Modbus RTU CRC-16校验码生成器 CRC_Calc v0.3 最新版

    **Modbus RTU CRC-16校验码生成器 CRC_Calc v0.3详解** 在工业自动化领域,数据通信的正确性和可靠性至关重要。其中,Modbus RTU(远程终端单元)是一种广泛应用的通信协议,它依赖于错误检测机制来确保数据在传输...

    mysql获取group by总记录行数的方法

    首先,MySQL提供了一个特殊的标志`SQL_CALC_FOUND_ROWS`,这个标志可以在查询时计算总的行数,而不仅仅是分组后的行数。使用`SQL_CALC_FOUND_ROWS`时,你需要在查询的开始部分加上这个标志,然后执行查询,再单独...

    LibreOffice_7.2.5_Linux_x86-64_deb_langpack_zh-CN.tar.gz

    1. **LibreOffice 7.2.5 版本**: 这是LibreOffice的一个稳定版本,7.2.5意味着它是7.2系列中的第五个小版本更新,通常包含错误修复、性能提升和用户体验改进。每个新版本都会对软件的功能、稳定性和兼容性进行优化。...

    Apache_OpenOffice_4.1.7_Linux_x86-64_install-rpm_zh-CN.tar.gz

    2. 电子表格程序Calc:类似于Excel,可进行数据计算、分析和图表制作。 3. 演示文稿软件Impress:用于制作动态幻灯片展示,支持丰富的动画和过渡效果。 4. 绘图工具Draw:可以创建矢量图形、流程图和图表。 5. ...

    CRC_Calc+v0.1

    CRC_Calc+v0.1 是一个专门用于计算CRC值的工具,支持多种CRC标准,如CRC-8和CRC-16等。 CRC计算的基本原理是基于多项式除法。每个CRC算法都与一个特定的生成多项式关联。例如,CRC-8通常使用生成多项式X^8 + X^2 + ...

    ads_order_calc_tact.sh

    ads_order_calc_tact.sh

    spwm_calc.zip

    标题“spwm_calc.zip”指的是一个包含SPWM(正弦脉宽调制)计算相关软件的压缩文件。这个软件可能是由教师提供的,用于教学或研究SPWM技术。SPWM是一种广泛应用在电力电子设备中的调制技术,特别是逆变器中,它通过...

    CRC_Calc .rar

    CRC_Calc是一个专门用于计算CRC值的软件工具,它支持多种CRC算法,能够帮助用户快速、准确地对数据进行校验。 CRC_Calc v0.1是这个压缩包中的主要程序,它可能是一个命令行工具或者具有图形用户界面的应用,使得非...

    Python库 | django_mysql-3.7.1-py3-none-any.whl

    6. **更高效的查询**:提供特定于MySQL的查询优化,例如使用`SQL_CALC_FOUND_ROWS`来获取分页结果的总数量。 7. **全文搜索**:利用MySQL的全文索引和搜索功能,实现更强大的文本搜索能力。 8. **自定义数据库引擎**...

    MYSQL中统计查询结果总行数的便捷方法省去count(*)

    在MySQL数据库中,当需要对查询结果进行统计,特别是涉及到分页或LIMIT限制时,`SQL_CALC_FOUND_ROWS` 是一个非常实用的关键词。这个关键词允许你在执行查询时同时计算满足条件的所有行数,而不仅仅是LIMIT返回的...

    SPWM波形生成工具spwm_calc_v1.3.2使用说明.pdf

    **SPWM波形生成工具spwm_calc_v1.3.2使用详解** SPWM(Sinusoidal Pulse Width Modulation,正弦脉宽调制)是一种常见的电力电子技术,广泛应用于电机驱动、逆变器和电源转换系统。SPWM工具spwm_calc_v1.3.2由作者...

    zhu_npp_calc.zip

    《朱文泉博士的ENVI净初级生产力计算模型详解》 ...NPP的估算对于理解生态系统的能量流动、碳循环以及气候变化的影响具有深远意义。朱文泉博士开发的NPP计算模型,为科研人员提供了便捷的工具,使得NPP的估算更加高效...

    Modbus RTU CRC-16校验码生成器CRC_Calc v0.2

    **Modbus RTU CRC-16校验码生成器CRC_Calc v0.2** Modbus RTU(Remote Terminal Unit)是一种广泛应用于工业自动化领域的通信协议,它基于串行通信,提供了一种设备间交换数据的标准方法。在Modbus RTU通信中,为了...

Global site tag (gtag.js) - Google Analytics