2017-10-18 5 views
-1

私はCodeigniterを使用していますが、現在検索エンジン(PHPシステム)を介してDBのリストを照会しようとすると、私はこの問題がクエリのコーディングに関連していると信じています。これは、DBを表示している残りのページが高速に読み込まれていて、日付の間にDBを検索していないためです。このページは、検索を実行すると10分以上の読み込みに似ています。日付の間に検索するとMYSQLのPHPクエリが遅くなります

IMG FOR tbl_transaction SHOW CREATE TABLE

上記のように

public function get_transaction_record($search,$per_pg,$offset){ 
     $fill = array((int)1); 
     $temp = array(); 
     $data = array(); 
     $sQuery = "SELECT t.*,p.product_name,d.deposit_id,w.withdrawal_id,m.username,m.lucky_id,m.contact_no,u.username as admin, 
        b.name as bankname,b.holder_name, d.promo as prm, m.fullname, d.turnover as tover 
        FROM tbl_transaction t 
        INNER JOIN tbl_product p ON t.product_id = p.product_id 
        INNER JOIN tbl_member m ON m.member_id = t.member_id 
        LEFT JOIN tbl_deposit d ON t.transaction_id = d.transaction_id 
        LEFT JOIN tbl_withdrawal w ON t.transaction_id = w.transaction_id 
        INNER JOIN tbl_banks b ON t.bank_id = b.bankID 
               LEFT JOIN tbl_promotion pro ON pro.promotion_id = d.promotion_id 
        LEFT JOIN tbl_user u ON u.user_id = t.admin_id WHERE 1 = ? AND t.status != 9"; 

     if(strlen($search['date_from']) > 0 && strlen($search['date_to']) > 0 ){ 
      $sQuery .= ' AND date(t.date_create) BETWEEN ? '; 
      array_push($fill,$search['date_from']); 

      $sQuery .= ' AND ? '; 
      array_push($fill,$search['date_to']); 
     }else{ 
      if(strlen($search['date_from']) > 0){ 
       $sQuery .= ' AND date(t.date_create) = ? '; 
       array_push($fill,$search['date_from']); 
      } 
      if(strlen($search['date_to']) > 0){ 
       $sQuery .= ' AND date(t.date_create) = ? '; 
       array_push($fill,$search['date_to']); 
      } 
     } 

     if(strlen($search['status']) > 0){ 
      $sQuery .= ' AND t.status = ? '; 
      array_push($fill,$search['status']); 
     } 
        if(strlen($search['contact_no']) > 0){ 
      $sQuery .= ' AND m.contact_no LIKE "%"?"%" '; 
      array_push($fill,$search['contact_no']); 
     } 

     if(strlen($search['fullname']) > 0){ 
      $sQuery .= ' AND m.fullname LIKE "%"?"%" '; 
      array_push($fill,$search['fullname']); 
     } 
     if(strlen($search['username']) > 0){ 
      $sQuery .= ' AND m.username LIKE "%"?"%" '; 
      array_push($fill,$search['username']); 
     } 

     if(strlen($search['lucky_id']) > 0){ 
      $sQuery .= ' AND m.lucky_id = ? '; 
      array_push($fill,$search['lucky_id']); 
     } 

     if(strlen($search['email']) > 0){ 
      $sQuery .= ' AND m.email LIKE "%"?"%" '; 
      array_push($fill,$search['email']); 
     } 

     if(strlen($search['user_id']) > 0){ 
      $sQuery .= ' AND t.admin_id = ? '; 
      array_push($fill,$search['user_id']); 
     } 

     if(strlen($search['product_id']) > 0){ 
      $sQuery .= ' AND t.product_id = ? '; 
      array_push($fill,$search['product_id']); 
     } 

     if(strlen($search['bankID']) > 0){ 
      $sQuery .= ' AND t.bank_id = ? '; 
      array_push($fill,$search['bankID']); 
     } 

     if(strlen($search['type']) > 0){ 
      $sQuery .= ' AND t.type = ? '; 
      array_push($fill,$search['type']); 
     } 

     if(strlen($search['bankid2']) > 0){ 
      $sQuery .= ' AND w.bankid2 = ? '; 
      array_push($fill,$search['bankid2']); 
     } 

    // $sQuery .= " ORDER BY t.date_create DESC LIMIT ?,? "; 
      $sQuery .= " ORDER BY t.date_create DESC LIMIT ?,? "; 
     // $sQuery .= " ORDER BY CASE t.status WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN -1 THEN 9 END, t.date_create DESC LIMIT ?,? "; 
     array_push($fill,(int)$offset,(int)$per_pg); 

     $query = $this->db->query($sQuery, $fill); 
     //echo $this->db->last_query(); 
     if($query->num_rows() > 0){ 
      foreach ($query->result() as $rows): 
       $temp['bankname']  = $rows->bankname; 
       $temp['holder_name'] = $rows->holder_name; 
       $temp['ref']   = $rows->ref; 
       $temp['username']  = $rows->username; 
       $temp['fullname']  = $rows->fullname; 
       $temp['lucky_id']  = $rows->lucky_id; 
       $temp['admin']   = $rows->admin; 
       $temp['contact_no']  = $rows->contact_no; 
       $temp['product_name'] = $rows->product_name; 
            $temp['promo'] = $rows->promo; 
       $temp['transaction_id'] = $rows->transaction_id; 

       $temp['member_id']  = $rows->member_id; 
       $temp['type']   = $rows->type; 
       $temp['product_id']  = $rows->product_id; 
       $temp['deposit_id']  = $rows->deposit_id; 
       $temp['withdrawal_id'] = $rows->withdrawal_id; 
       $temp['amount']   = $rows->amount; 
            $temp['turnover']   = $rows->turnover; 
       $temp['status']   = $rows->status; 
       $temp['remark']   = $rows->remark; 
       $temp['day']   = $rows->day; 
       $temp['month']   = $rows->month; 
       $temp['year']   = $rows->year; 
       $temp['date_create'] = $rows->date_create; 
       $temp['date_update'] = $rows->date_update; 
       $temp['create_by']  = $rows->create_by; 
            $temp['prm']   = $rows->prm; 
            $temp['tover']   = $rows->tover; 
            if($rows->promotion_id > 0){ 
              $temp['promo'] = $this->get_promotion_details($rows->promotion_id); 
            }else{ 
              $temp['promo'] = NULL; 
            } 
       array_push($data, $temp); 
      endforeach; 
     } 
     return $data; 
    } 

更新されたコードを感謝を:それは私のコーディングで何か間違っているか、いずれかの専門家は私のコーディングを改善するために、私に、より良い提案を提供してくださいすることができます確認してください。

+3

クエリ最適化のヘルプを求めるときは、常にクエリのすべてのテーブルの 'SHOW CREATE TABLE'とクエリの' EXPLAIN'を投稿してください。最終的なSQLを把握するためのコードをトレースしないでください。 SQL文字列を作成するコードではなく、SQLを表示します。 –

+0

@Randall非常に長いリストは、システムが1日に10k行以上のdbエントリを含んでいたためです。しかし、特定の日付を検索せずにページを表示するとかなり高速にロードされます。 –

+0

'date()'はインデックスを使用できません。 – Strawberry

答えて

1

まず、トランザクションテーブルに対して定義されたインデックスがありません。したがって、すべての検索はテーブルスキャンを強制されます。インデックスを使用して検索を高速化することは重要です。

私のプレゼンテーションが好きかもしれません。How to Design Indexes, Reallyまたはビデオ:https://www.youtube.com/watch?v=ELR7-RdU9XU

は、これはおそらく、あなたが作成するための最も重要な指標である:

ALTER TABLE tbl_transaction ADD INDEX (create_date); 

しかし、あなたは、次のような式で検索しようとすると、インデックスを持った後でも、それができますインデックスを使用しないでください。

date(t.date_create) BETWEEN ? AND ? 

あなたはそう索引列は一人である、それを書き換える必要があります:

t.date_create BETWEEN ? AND ? 

しかし、これはあなたが最初のパラメータは、時間午後12時○○分00秒、2番目のパラメータに「床の」したいこと「天井」から時刻23:59:59に変更して、date_createを任意の時刻コンポーネントと一致させたい日付範囲に一致させるようにします。

if(strlen($search['date_from']) > 0 && strlen($search['date_to']) > 0 ){ 
    $from = search['date_from'] . ' 00:00:00'; 
    $to = search['date_to'] . ' 23:59:59'; 

    $sQuery .= ' AND t.date_create BETWEEN ? AND ?'; 
    array_push($fill,$from); 
    array_push($fill,$to); 
} 

同様に、一つでも特定の日付を検索するために、あなたはまだ範囲をしなければならない。

else if(strlen($search['date_from']) > 0){ 
    $from = search['date_from'] . ' 00:00:00'; 
    $to = search['date_from'] . ' 23:59:59'; 

    $sQuery .= ' AND t.date_create BETWEEN ? AND ?'; 
    array_push($fill,$from); 
    array_push($fill,$to); 
} 

あなたはインデックスを設計する上で、私のプレゼンテーションを読めば、あなたは気づいているだろう、その範囲の条件create_dateのように、索引の後続の列が検索に役立たないことを意味します。複数列の索引を使用できますが、等価条件に関係するすべての列は索引の左になければなりません。

また、ユーザーの検索条件に基づいて複数の条件が存在する場合と存在しない場合があります。索引検索では、索引の列が左から右へのみ使用されるため、これも最適化するのは難しいです。検索で必要としないために列をスキップすると、それ以降の列は役立ちません。

検索条件のもう1つのタイプは、等価条件ではなく、LIKE '%'?''のテキストパターンマッチングです。これらのLIKE検索では従来のインデックスは使用できませんが、特別なfulltext search indexを使用できます。私はそれについてのプレゼンテーションを持っています:Full Text Search Throwdown。ビデオ:https://www.youtube.com/watch?v=V8yA8C3CZOc

関連する問題