• <acronym id="vs0le"><strong id="vs0le"></strong></acronym>

    <pre id="vs0le"><s id="vs0le"><menu id="vs0le"></menu></s></pre>

    <table id="vs0le"></table>

    1. <pre id="vs0le"></pre>
      軟件培訓網

      歡迎訪問軟件培訓網!招生咨詢電話與微信:15225191462(周老師)
      軟件培訓網,專業解決學IT疑難雜癥!

      首頁 > php技術/ 正文

      PHP 中 MySQL 數據庫異步查詢實現

      2016-06-23 15:48:03 軟件培訓網

      PHP 中 MySQL 數據庫異步查詢實現?Cf0軟件培訓網

      問題
      通常一個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數據庫負載不高的情況下,使用異步查詢還是不錯的選擇。

      Tags:河南鄭州全棧工程師培訓基地在哪,鄭州北大青鳥IT培訓靠譜嗎,鄭州北大青鳥java培訓課程包含哪些內容,鄭州java培訓學校哪家比較好呢,鄭州大數據培訓機構教你如何學好大數據課程,鄭州軟件培訓學軟件開發需要什么基礎

      搜索
      軟件培訓學校哪家好,就來軟件培訓網咨詢
      軟件培訓學校哪家好,就來軟件培訓網咨詢
      熱門標簽
      軟件培訓學校哪家好,就來軟件培訓網咨詢
      軟件培訓學校哪家好,就來軟件培訓網咨詢
      軟件培訓學校哪家好,就來軟件培訓網咨詢
      • QQ交談
      日本AV网站

    2. <acronym id="vs0le"><strong id="vs0le"></strong></acronym>

      <pre id="vs0le"><s id="vs0le"><menu id="vs0le"></menu></s></pre>

      <table id="vs0le"></table>

      1. <pre id="vs0le"></pre>