🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# swoole\_mysql\_query [TOC] 异步地执行一条SQL语言,需要依赖MySQLi和mysqlnd扩展。此函数是swoole底层提供的真异步函数。解决了PHP官方`mysqli->reap_async_query`方法存在的2个严重问题。 1. `mysqli->reap_async_query`的recv缓冲区设置过小,在读取较大的RecordSet时会浪费大量read系统调用,性能不佳 2. MySQL服务器的RecordSet可能会分段发送,`mysqli->reap_async_query`方法会阻塞。导致程序退化为同步阻塞模式。并发能力大大降低 `swoole_mysql_query`底层使用`64K`内存缓冲区,即使读取很大的RecordSet也仅需少量的read系统调用。另外`swoole_mysql_query`借助swoole提供的Epoll接口异步读取MySQL服务器的`RecordSet`,整个过程没有任何阻塞。 ## 函数原型 ~~~ function swoole_mysql_query(mysqli $link, string $sql, callable $callback); ~~~ * $link为已连接的mysqli对象 * $sql为要执行的SQL语句 * $callback执行成功后会回调此函数 * 每个MySQLi连接只能同时执行一条SQL,必须等待返回结果后才能执行下一条SQL > swoole\_mysql\_query需要swoole-1.8.0或更高版本,并且仅可用于CLI命令行环境 > 1.8.6或更高版本已移除 ## 回调函数 ~~~ function onSQLReady(mysqli $link, mixed $result); ~~~ * 执行失败,`$result`为`false`,读取`$link`对象的`_error`属性获得错误信息,`_errno`属性获得错误码 * 执行成功,SQL为非查询语句,`$result`为`true`,读取`$link`对象的`_affected_rows`属性获得影响的行数,`_insert_id`属性获得`Insert`操作的自增ID * 执行成功,SQL为查询语句,`$result`为结果数组 ## 使用示例 ~~~ $db = new mysqli; $db->connect('127.0.0.1', 'root', 'root', 'test'); $sql = "SELECT * FROM `userinfo` LIMIT 0, 10000"; $s = microtime(true); swoole_mysql_query($db, $sql, function(mysqli $db, $r) { global $s; //SQL执行失败了 if ($r == false) { var_dump($db->_error, $db->_errno); } //执行成功,update/delete/insert语句,没有结果集 elseif ($r == true) { var_dump($db->_affected_rows, $db->_insert_id); } //执行成功,$r是结果集数组 else { echo "count=".count($r).", time=".(microtime(true) - $s), "\n"; var_dump($r); swoole_mysql_query($db, "show tables", function ($db, $r) { var_dump($r); }); } }); ~~~