2017-03-19 8 views
1

オートコンプリートコードのパフォーマンスに問題があります。 次のクエリは、結果を返すためにキーストロークあたり約2〜3秒かかります。オートコンプリートのパフォーマンス上の問題

はコード厥:

$keywords = $_POST["keyword"]; 
    $keywordsplit = explode(' ', $keywords); 
    $limit = $_POST["limit"]; 

    $columnnames = array("ag_address_files.primary_mail", 
         "ag_address_files.secondary_mail", 
         "ag_address_files.tertiary_mail", 
         "ag_address_files.quaternary_mail", 
         "ag_orders.order_main_id", 
         "ag_orders.order_marketplace_order_id", 
         "ag_addresses.address_company_1", 
         "ag_addresses.address_first_name", 
         "ag_addresses.address_last_name", 
         "ag_addresses.address_street", 
         "ag_addresses.address_city"     
         ); 

    $sql = "SELECT DISTINCT ag_address_files.customer_id, 
          ag_address_files.first_name, 
          ag_address_files.last_name, 
          ag_address_files.company_1, 
          ag_address_files.primary_mail, 
          ag_address_files.phone_number, 
          ag_addresses.address_street, 
          ag_addresses.address_house_number, 
          ag_addresses.address_street_complete, 
          ag_addresses.address_post_code, 
          ag_addresses.address_city 

      FROM ag_address_files 
      LEFT JOIN ag_orders ON ag_address_files.customer_id = ag_orders.order_customer_id 
      LEFT JOIN ag_addresses ON ag_address_files.customer_id = ag_addresses.address_customer_id"; 

    $i = 0;  
    foreach($keywordsplit as $keyword) { 
     $ii = 0; 
     $keys = trim($keyword);  

     foreach($columnnames as $columns) {   
      if ($i == 0 AND $ii == 0) { 
      $sql .= " WHERE (" . $columns . " like '%" . $keys . "%'";  
      } elseif ($ii == 0) { 
      $sql .= " AND (" . $columns . " like '%" . $keys . "%'";  
      } else { 
      $sql .= " OR " . $columns . " like '%" . $keys . "%'"; 
      } 
     $ii++; 
     } 

     $sql .= ")";  
     $i++;  
    } 

    $sql .= " ORDER BY ag_address_files.date_added DESC LIMIT 0, " . $limit;  

そして、生成されたSQL文字列that's:

SELECT DISTINCT ag_address_files.customer_id, ag_address_files.first_name, ag_address_files.last_name, ag_address_files.company_1, ag_address_files.primary_mail, ag_address_files.phone_number, ag_addresses.address_street, ag_addresses.address_house_number, ag_addresses.address_street_complete, ag_addresses.address_post_code, ag_addresses.address_city 

    FROM ag_address_files 
    LEFT JOIN ag_orders ON ag_address_files.customer_id = ag_orders.order_customer_id 
    LEFT JOIN ag_addresses ON ag_address_files.customer_id = ag_addresses.address_customer_id 

    WHERE (ag_address_files.primary_mail like '%hansen%' OR ag_address_files.secondary_mail like '%hansen%' OR ag_orders.order_main_id like '%hansen%' OR ag_orders.order_marketplace_order_id like '%hansen%' OR ag_addresses.address_company_1 like '%hansen%' OR ag_addresses.address_first_name like '%hansen%' OR ag_addresses.address_last_name like '%hansen%' OR ag_addresses.address_city like '%hansen%') 

    ORDER BY ag_address_files.date_added DESC LIMIT 0, 10 

WHEREおよびORDER句のすべての列がインデックス化されています。 $ columnnames配列はすでに縮小バージョンです。このクエリの目的は、指定されたキーワードを検索し、すべてのキーワードが一致する結果を返すことではありません。

あなたはどう思いますか? WHERE句は過剰ですか?事前に

おかげ

種類は、私が自分でこの問題を解決できる一方で ケビン

答えて

0

について。

%ワイルドカードを最初に使用すると、MYSQLはテキスト列のインデックスを使用できません。そのため、私はIndex TypeをFulltextに変更しましたが、今は "Match against Against"ステートメントを使用しています。

左結合列にも索引がありませんでした。

クエリには約0.050秒しかかかりません。

ケア ケビン

関連する問題