如何过早地完成mysql_use_result()/ mysql_fetch_row()?

时间:2017-11-14 13:51:56

标签: mysql c libmysql

我正在为MySQL 5.5编写我的第一个C客户端,并且在文档中偶然发现了the following page。几乎在最后,它表示(大胆强调我的,斜体强调不是我的):

  

mysql_use_result()的一个优点是[...]。缺点是   [...]。 此外,即使您必须检索所有行   在检索中期确定您已找到您所获得的信息   寻找。

最后一句话对我来说并不清楚。

1)如果我不遵循该行,会发生什么?

2)我认为如果我确定我有足够的信息,那么实际上必须有一种过早结束提取行的方法(否则,这一切在我看来并没有多大意义)。

我知道如果我只是停止获取行然后尝试执行下一个语句,那么可能会发生一些不好的事情,但是不存在类似mysql_finish_fetch()之类的函数吗?

如果我致电mysql_free_result()会怎样?即使我还没有获取所有行,这应该可以释放结果,所以在检索中调用它并继续我想做的任何事情都应该是安全的。我错了吗?

1 个答案:

答案 0 :(得分:2)

这听起来像MySQL暴露给客户端的内部线程问题。将它归结为各种MySQL gotchas。缺点是MySQL在内部显然拥有有限数量的“搜索者”,并且使用mysql_use_result()显然将其中一个专用于您的API请求。此外,MySQL显然没有公开的API调用来取消这样的请求。唯一的选择是看到提取直到结束。

稍长的版本:在内部,MySQL的游标显然只有一个代码路径 - 我想象在常见情况下的性能。当光标找不到更多结果时,该代码路径仅退出 。当您使用更常见的mysql_store_result()时,MySQL已经在将结果返回给应用程序之前完成了此操作。但是,当您使用mysql_use_result()时,MySQL要求您执行“脏工作”来迭代结果集的其余部分以清除光标。乐趣。

来自documentation

  

mysql_use_result()启动结果集检索,但实际上并没有像mysql_store_result()那样将结果集读入客户端。相反,必须通过调用mysql_fetch_row()来单独检索每一行。这直接从服务器读取查询结果,而不将其存储在临时表或本地缓冲区中,这比mysql_store_result()更快,使用的内存更少。客户端仅为当前行和可能长达max_allowed_packet字节的通信缓冲区分配内存。

     

另一方面,如果对客户端的每一行进行大量处理,或者输出发送到用户可能使用的屏幕,则不应使用mysql_use_result()来锁定读取。输入^S(停止滚动)。这会占用服务器并阻止其他线程更新从中获取数据的任何表。

     

使用mysql_use_result()时,必须执行mysql_fetch_row(),直到返回NULL值,否则,未获取的行将作为下一个查询的结果集的一部分返回。如果您忘记这样做,C API会给出错误Commands out of sync; you can't run this command now

所以,要真正回答你的问题:

  

1)如果我不遵循该行,会发生什么?

C API将返回错误消息:Commands out of sync; you can't run this command now

  

2)我认为如果我确定我有足够的信息,那么实际上必须有一种过早结束提取行的方法(否则,这一切在我看来并没有多大意义)。

有人会想,但没有。您必须完全迭代结果集。