3

ユーザーが検索できる大量のデータを含むデータベースがあると想像してみてください。
通常の検索の結果は、通常、約20〜100行で、その後ページ分割されます(1ページあたり20行)。

私はこれらのページのナビゲーションを処理するための2つのアプローチを考えました。これらに賛否両論があるかどうか、そしてより良い代替案があるかどうかを知りたいと思います。

  1. 一度クエリを実行し、結果を変数に保存し、$_SESSION現在のページに従って行をフィルタリングします。私がこれを思いついた理由は、ユーザーがナビゲートするすべてのページでデータベースに接続することなく、データを1回取得するためでした。私が思いついた他の選択肢よりも良いか悪いかはわかりません。

    session_start();
    
    $search = rawurldecode($_GET['search']);   //search word
    $interval = rawurldecode($_GET['interval']); //rows per page
    $page = rawurldecode($_GET['page']);    //page
    
    $min_row = $interval * ($page-1)+1;
    $max_row = $interval * $page;
    
    //query if (no results stored or first page) && the current search is not the previous search                               
    if((empty($_SESSION['SEARCH_RESULTS']) || $page == 1) && $_SESSION['SEARCH_RESULTS']['TERM'] != $search){
        $_SESSION['SEARCH_RESULTS'] = array();
        $_SESSION['SEARCH_RESULTS']['TERM'] = $search;
    
        $query = "exec usp_Search '$search'";
    
        $dbh = new DBH;
        $dbh->Connect()->Query($query);
    
        while($row = $dbh->Fetch_Array()){  
            $_SESSION['SEARCH_RESULTS']['ROWS'][] = $row;                           
        }
    }
    
    for($j = 0; $j < count($_SESSION['SEARCH_RESULTS']['ROWS']); $j++){
        $row = $_SESSION['SEARCH_RESULTS']['ROWS'][$j];
    
        //ignore all other rows not on the page
        if($j < ($min_row-1) || $j > $max_row) continue; 
    
        //print stuff
    }
    
  2. ページごとにクエリします。クエリとページネーションは非常に簡単です。

    //Query
    $search = rawurldecode($_GET['search']);
    $interval = rawurldecode($_GET['interval']);
    $page = rawurldecode($_GET['page']);
    
    $min_row = $interval * ($page-1)+1;
    $max_row = $interval * $page;
    
    $query = "exec usp_Search '$search', $min_row, $max_row";
    
    $dbh = new DBH;
    $dbh->Connect()->Query($query);
    
    while($row = $dbh->Fetch_Array()){ 
        //print stuff                       
    }
    

代替からのSQLプロシージャ

  1. SELECTクエリを使用した単なるプロシージャです

    SELECT 
        COL1,
        COL2,
        COL...
    FROM TABLE1
    WHERE (
        COL1 LIKE '%'+@search+'%' OR 
        COL2 LIKE '%'+@search+'%' OR 
        COL... LIKE '%'+@search+'%'
    )
    
  2. 一時テーブルを作成し、変数の最初から最後まで行を選択するプロシージャです。

    SELECT 
        COL1,
        COL2,
        COL...,
        ROW_NUMBER() OVER (ORDER BY COL1) AS [ROW_NUMBER]
    INTO #result
    FROM TABLE1
    WHERE (
        COL1 LIKE '%'+@search+'%' OR 
        COL2 LIKE '%'+@search+'%' OR 
        COL... LIKE '%'+@search+'%'
    )   
    
    SELECT 
        COL1,
        COL2,
        COL...
    FROM #result
    WHERE ROW_NUMBER BETWEEN @row_start AND @row_end
    
4

2 に答える 2

0

_SESSION少なくともいくつかの理由により、すべての結果をに保存することはできません。

  • ユーザーは同時に複数の検索を行うことができます
  • 検索結果は、ユーザーのページの読み込みごとに変わる可能性があります。

2番目のポイントは、DBを更新する頻度によって異なりますが、考慮すべき点です。1つ目はメジャーですが、セッションを巧妙な方法で保存すれば回避できる場合もあります(ただし、_SESSION大きくなりすぎないようにする必要もあります)。これはパフォーマンスに関係ありません。

すべての結果を一度に取得して保存することに関するもう1つの考慮事項_SESSIONは、ユーザーの大多数が1回の訪問につき1つの検索リクエストしか作成できないことです。100件すべての結果が常に表示されると思いたいのですが、それらの結果の大部分が使用されていない場合は、クエリを1つか2つ保存するだけでかなりの無駄になります。ユーザーがどのようにナビゲートするかを理解するのはあなた次第です。


これは20〜30人で1日70行しか使用されないことを読んだ後、この時点でパフォーマンスを向上させるために時間を無駄にしていると言って満足しています。大きな変更があった場合に後で更新しやすいコードを探してください。

于 2012-06-20T15:46:20.210 に答える
0

このシナリオを考えてみましょう。

  • ユーザーは、データベースに保存されている100件の結果を含む用語を検索します。
  • 100個の結果すべてを取得したら、データベースにクエリを実行し、それらをセッションに保存します。
  • ユーザーは最初の5つの結果で探していたものを見つけ、検索ページを離れます。

最後に、データベースを「過熱」して、95行を無料でフェッチしました。それらの100の結果が1000、または10.000である場合はどうなりますか?

私の意見では、すべての結果を1つのクエリで取得し、その結果をセッションに保存することは、パフォーマンスを低下させるための「信頼できる方法」です。

于 2012-06-20T16:40:04.243 に答える