MySQL如何将查询结果发送给客户端

MySQL的边查边发机制,可以结合以下文字和图片阅读:
请添加图片描述
当要执行一个大查询时,MySQL会将查询结果分批次发送给客户端,并不是在服务端查到所有数据后一次性发送给客户端;

Server层:

MySQL通过将查询到的结果依次存入net_buffer中,按页发送给客户端,并且在net_buffer发送数据给客户端的过程中,MySQL继续执行查询操作(边查边发),但是只有等客户端完全接受了net_buffer中的数据后,net_buffer才会清空,MySQL才能将最近查到的数据写入net_buffer中。

所以客户端读取速度会影响MySQL发送数据的速度。一般客户端有两种读取数据的方法:

  • mysql_use_result:这个设置使得客户端按行从net_buffer中读取数据,读一行去执行一遍用户的逻辑操作,大大加长了读取数据的时间,所以MySQL经常会卡在将数据写入net_buffer的环节(MySQL查询线程处于Sending to client状态)。
  • mysql_store_result:该设置时,客户端会一次性将net_buffer中的数据放入内存中,之后再去执行用户的逻辑操作,这样net_buffer就会很快清空,MySQL可以无阻塞写入,但是查询结果多的时候,客户端内存被占用率大。

InnoDB层

再看一下MySQL的InnoDB层是如何具体执行查询操作的(改进的LRU算法),LRU最近最少使用算法基本流程如下:

  1. 首先MySQL会去内存中找数据页,内存中多张数据页以链表的顺序存储(按照最近被访问的数据页放在最前面的原则),依次从头结点访问尾节点,如果命中内存,直接读取数据到server层,然后server层将数据写入到net_buffer。
  2. 如果内存中不存在该数据,就去磁盘IO查询数据页,因为该数据页是最新被访问的,所以加入到链表的头结点
  3. 当链表中节点满了,就要先删除尾节点(最久未被访问的数据页),再插入头结点的最新从磁盘读取的数据页。

为了提高MySQL的查询速度,最主要的就是提高InnoDB层的内存命中率,MySQL在以上LRU算法的基础上进行了改进,进一步提高了内存命中率。

参考文章:

https://time.geekbang.org/column/article/79407

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用AJAX长轮询技术来实现MySQL数据库变化时向客户端发送消息通知。 具体实现步骤如下: 1. 在客户端代码中使用AJAX发送一个请求到服务器端。 2. 服务器端接收到请求后,执行一个无限循环,等待MySQL数据库的变化。 3. 当MySQL数据库发生变化时,服务器端将变化的信息返回给客户端。 4. 客户端接收到服务器端返回的信息后,再次发送请求,继续等待下一次MySQL数据库的变化。 以下是一个简单的示例代码,供您参考: 客户端代码: ```javascript function longPolling() { $.ajax({ url: 'server.php', type: 'GET', async: true, timeout: 30000, // 设置超时时间 cache: false, success: function(data) { // 处理服务器返回的数据 console.log('接收到服务器返回的数据:' + data); longPolling(); // 再次发送请求 }, error: function(XMLHttpRequest, textStatus, errorThrown) { if (textStatus == 'timeout') { console.log('请求超时,重新发送请求'); longPolling(); // 再次发送请求 } else { console.log('请求错误:' + errorThrown); } } }); } $(function() { longPolling(); }); ``` 服务器端代码(使用PHP实现): ```php header('Content-type: text/html; charset=utf-8'); // 连接MySQL数据库 $link = mysqli_connect('localhost', 'root', 'password', 'test'); if (!$link) { die('连接MySQL数据库失败:' . mysqli_connect_error()); } // 执行长轮询 while (true) { // 查询MySQL数据库,判断是否发生变化 $result = mysqli_query($link, 'SELECT COUNT(*) FROM `table`'); $row = mysqli_fetch_row($result); $count = $row[0]; if ($count > 0) { // 如果发生变化,返回变化的信息 echo $count; exit; } else { // 如果没有发生变化,等待一段时间再查询 sleep(1); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值