php中mysql資料庫異步查詢實現

2022-01-30 PHP老楊

問題

通常一個web應用的性能瓶頸在資料庫。因為,通常情況下php中mysql查詢是串行的。也就是說,如果指定兩條sql語句時,第二條sql語句會等到第一條sql語句執行完畢再去執行。這個時候,如果執行2條sql語句,每條執行時間為50ms,全部執行完畢可能需要100ms。既然,主要原因是sql的串行執行導致。那我們是不是可以改變執行方式來提高性能呢?答案是,可以的。我們可以通過異步執行的方式來提高性能。
異步

如果通過異步的方式去執行,可能性能會有很大提升。如果是採用異步的方式,兩條sql語句會並發執行,可能就需要60ms就可以執行完畢。
實現

mysqli + mysqlnd。php官方實現的mysqlnd中提供了異步查詢的方法。分別是:
mysqlnd_async_query 發送查詢請求
mysqlnd_reap_async_query 獲取查詢結果
這樣就可以不必每次發送完查詢請求後,一直阻塞等待查詢結果了。

實現代碼如下:

<!--?php
   
$host       = '127.0.0.1';
$user       = 'root';
$password   = '';
$database   = 'test';
   
/**
 * 期望得到額結果
 * array(
 *  1 =--> int,
 *  2 => int,
 *  3 => int
 * )
 */
$result = array(1=>0, 2=>0, 3=>0);
   
//異步方式[並發請求]
$time_start = microtime(true);
$links = array();
   
foreach ($result as $key=>$value) {
    $obj = new mysqli($host, $user, $password, $database);
    $links[spl_object_hash($obj)] = array('value'=>$key, 'link'=>$obj);
}
$done = 0;
$total = count($links);
   
foreach ($links as $value) {
    $value['link']->query("SELECT COUNT(*) AS `total` FROM `demo` WHERE `value`={$value['value']}", MYSQLI_ASYNC);
}
   
do {
   
    $tmp = array();
    foreach ($links as $value) {
        $tmp[] = $value['link'];
    }
   
    $read = $errors = $reject = $tmp;
    $re = mysqli_poll($read, $errors, $reject, 1);
    if (false === $re) {
        die('mysqli_poll failed');
    } elseif ($re < 1) {
        continue;
    }
   
    foreach ($read as $link) {
        $sql_result = $link->reap_async_query();
        if (is_object($sql_result)) {
            $sql_result_array = $sql_result->fetch_array(MYSQLI_ASSOC);//只有一行
            $sql_result->free();
            $hash = spl_object_hash($link);
            $key_in_result = $links[$hash]['value'];
            $result[$key_in_result] = $sql_result_array['total'];
        } else {
            echo $link->error, "\n";
        }
        $done++;
    }
   
    foreach ($errors as $link) {
        echo $link->error, "1\n";
        $done++;
    }
   
    foreach ($reject as $link) {
        printf("server is busy, client was rejected.\n", $link->connect_error, $link->error);
        //這個地方別再$done++了。
    }
} while ($done<$total);
var_dump($result);
echo "ASYNC_QUERY_TIME:", microtime(true)-$time_start, "\n";
   
$link = end($links);
$link = $link['link'];
echo "\n";


 結語

mysql資料庫對於每個查詢請求都是單獨啟動一個線程進行處理。如果mysql伺服器啟動線程過多,必然會造成線程切換引起系統負載過高。如果在mysql資料庫負載不高的情況下,使用異步查詢還是不錯的選擇。
參考文檔

http://www.walu.cc/php/async-mysql-query.md

相關焦點

  • 從Web查詢資料庫之PHP與MySQL篇
    從Web查詢資料庫:Web資料庫架構的工作原理 一個用戶的瀏覽器發出一個HTTP請求,請求特定的Web頁面,在該頁面中出發form表單提交到php腳本文件(如:results.php)中處理 Web伺服器接收到對results.php頁面的請求後,檢索文件,並將其傳遞給PHP引擎處理 PHP引擎開始解析腳本
  • PHP 使用 Swoole - TaskWorker 實現異步操作 Mysql
    要實現上述的異步處理,只需要增加兩個事件回調即可:onTask 和 onFinish, 這兩個回調函數分別用於執行 Task 任務和處理 Task 任務的返回結果。另外還需要在 set 方法中設置 task 進程數量。
  • 詳解PHP操作MySQL資料庫
    2)Web伺服器收到.php 的請求獲取該文件,並將它傳到 PHP 引擎,要求它處理。3)PHP 引擎開始解析腳本。 腳本中有一條連接資料庫的命令, 還有執行一個查詢的令。命PHP 打開通向 MYSQL 資料庫的連接,發送適當的查詢。4)MYSQL 伺服器接收資料庫查詢並處理。將結果返回到 PHP 引擎。
  • PHP MySQL資料庫編程
    注意:該選項在php.ini中默認是開啟的,mysqli為前綴的函數,可以直接在代碼中調用。1.3PDO 擴展連接PDO (PHP數據對象)是PHP5.1之後才支持的,是PHP應用中的一個資料庫抽象層規範。
  • (進階篇)PHP+Mysql+jQuery實現查詢和列表框選擇操作
    本文講解如何通過ajax查詢mysql數據,並將返回的數據顯示在待選列表中,再通過選擇最終將選項加入到已選區,可以用在許多後臺管理系統中。本文列表框的操作依賴jquery插件:Multiselect。<link rel="stylesheet" type="text/css" href="jquery.multiselect2side.css" /> 本例中只加載了Multiselect插件所需的樣式文件,其他CSS大家可以自行設計。首先需要引用本例所需的兩個js文件。
  • mysql查詢資料庫導致中文亂碼
    mysql查詢資料庫,如果資料庫裡的欄位的值是中文,就會出現亂碼,怎麼解決呢?看下面的講解寫一個test.php的文檔,代碼如下所示,打開mysql的界面,新建一個xml的資料庫,再建一個student的數據表,欄位值和記錄如下圖所示,打開谷歌瀏覽器,運行test.php文檔。運行結果是下圖:看到了吧,出現亂碼了,怎麼辦呢?
  • 實例,PHP+MySql 實現簡單的分頁功能
    1、mysql limit 用法SELECT * FROM table limit [offset,] count;參數:count 規定返回的數量簡單示例:SELECT * FROM user limit 10; // 取前 10 條數據SELECT * FROM user limit 10,10; // 查詢
  • PHP+MySQL應用中使用XOR運算加密算法
    ,包含資料庫配置信息7require_once("encrypy_xor.php");//包含xor加密函數文件89//連接資料庫10$link_id=mysql_connect($DBHOST,$DBUSER,$DBPWD);11mysql_select_db($DBNAME);//選擇資料庫my_chat12
  • (進階篇)PHP訪問MySQL資料庫的方法一
    使用PHP的mysql_*函數組訪問MySQL資料庫 <?php         $conn=mysql_connect("hostname","username","password") or die("連結資料庫失敗");         mysql_select_db("<database>");    $sql="<SQL statements>";
  • 五個常見 PHP 資料庫問題
    本文說明了資料庫設計和訪問資料庫的PHP代碼中出現的五個常見問題,以及在遇到這些問題時如何修復它們。問題1:直接使用MySQL一個常見問題是較老的PHP代碼直接使用mysql_函數來訪問資料庫。清單1展示了如何直接訪問資料庫。
  • MySQL中插入datetime時的PHP date()格式
    當使用PHP在MySQL中編寫查詢時,它的適用性將基於MySQL本身進行檢查。:CREATE DATABASE Date_time_example;示例1:用於創建資料庫和表的PHP程序<?); }    mysqli_close($conn);輸出:Table date_test created successfully示例2:將日期插入表中的PHP程序。
  • php與MySQL(基本操作)
    $conn){die("Connection failed: " . mysqli_connect_error());}創建資料庫mysqli_query()在php中,執行mysql語句,都要用到mysqli_query()方法。
  • 考前複習必備MySQL資料庫(關係型資料庫管理系統)
    查看數據表查看表分:查看資料庫中包含哪些表查看某個表的具體結構使用的語句有show語句和describe語句。使用describe語句可以查看表的各個欄位名稱,類型,長度,是否非空,是否有主鍵,默認值以及備註等信息。修改數據表可以修改表名,欄位名,欄位類型等表結構,可使用alter語句來實現修改操作。
  • PHP和MySQL實現簡單的網頁計數器
    源 / php中文網      源 / www.php.cn網站統計數據為網站所有者提供關於網站運行情況和訪問人數的重要信息。點擊計數器計數並顯示有多少人訪問一個網頁。計數器將命中總數存儲在MySQL資料庫中。首先,創建一個表來保存計數器統計信息。
  • php mysql PDO 查詢操作的實例詳解
    http://www.jb51.net/article/124388.htm這篇文章主要介紹了php mysql PDO
  • PHP異步網絡通信引擎-Swoole的安裝與應用
    Swoole簡介Swoole 使用純 C 語言編寫,提供了 PHP 語言的異步多線程伺服器,異步 TCP/UDP 網絡客戶端,異步 MySQL,異步 Redis,資料庫連接池,AsyncTask,消息隊列,毫秒定時器,異步文件讀寫,異步DNS查詢。
  • MySQL 刪除資料庫 | Mysql Drop Database
    在刪除資料庫過程中,務必要十分謹慎,因為在執行刪除命令後,所有數據將會消失。drop 命令刪除資料庫mysql> drop database RUNOON;使用 mysqladmin 刪除資料庫你也可以使用 mysql mysqladmin 命令在終端來執行刪除命令。
  • MySQL資料庫及應用
    查詢答案: A7 單選 資料庫、資料庫管理和資料庫系統之間的關係正確的是A. 資料庫包括了資料庫管理系統和資料庫系統B. 資料庫管理系統包括了資料庫和資料庫系統C.SHOWDATABASE;答案: C3 單選 關於資料庫的執行操作,_____________選項是錯誤的。A. SHOWDATABASES語句用於查詢當前資料庫系統中已經存在的資料庫B.
  • PHP中對資料庫操作的封裝
    現在我們把其封裝在dbfz.inc中,其設計如下:$#@60;?classdbInterface{var$dbID=1;//用於確定當前操作的資料庫,當dbID為1代表MySql,當為2代表SQLServer,為3時為ODBC或其它。
  • OpenResty、PHP-fpm與NodeJs操作MySQL的性能對比
    的投遞今天agentzh在微博上公布了一些OpenResty 與 php-fpm、Nodejs操作MySQL的性能評測數據。agentzh:我剛才在對比測試大結果集查詢時,發現NodeJS在使用 node-mysql庫訪問MySQL時,上下文切換次數居高不下,都快趕上 php-fpm + php-mysql了。