2016-07-01 12 views
0

私の状況ではLIMITの使用について指示されている回答は問題ではありませんが、LIMITの制限と不完全さを誤解する可能性があります。あるいは、私は間違った質問をしているかもしれません。これはこの質問を正当なものにします。SELECTクエリから1000行を取得する方法を教えてください。 MySQL

私は掻き取りする必要があるURLですその値は「URL」と呼ばれるフィールドが含まれ、「child_pages」と呼ばれるテーブルを持っています。そのURLに属するページをスクラップすると、結果のコンテンツhtmlは "content"というフィールドに格納されます。 child_pagesテーブルには200,000レコードがあります。

テーブルには「スキャンされた」フィールドと「処理された」フィールドもあります。両方ともtinyintなので、「1」=はい、この行がスキャンされ、「1」と言うことができます。

私がローカルサービス(Windows)として設定したスクリプトは、child_pagesテーブルを読み込み、urlフィールドから値を読み取り、スクレイプを実行し、最終的に結果のhtmlをcontentフィールドに格納します。これが完了すると、「スキャンされた」フィールドに「1」とマークされます。

は今、別のスクリプトは、「1」=スキャンされたすべてのレコードを探してchild_pagesテーブルを照会され、個別に実行されているが、処理される=「0」。その結果セットから、処理されていないレコードからcontentフィールドのhtml値を読み込み、最後に "content"フィールドhtmlから抽出したデータで何かを実行します。

これが私のクエリです:

$sql = "SELECT id,content FROM child_pages WHERE scanned='1' AND processed='0' LIMIT 1000"; 

私は処理が非常に遅いことに気付きました。私は5秒ごとに処理されるレコードを1つずつ取得します。私は一度に1000行を選択しているとき、どう考えていますか?

だから私は、whileループ内のループのカウンタを出力し、そして私はそれが数え$ = 1000を返しません見つけるのではなく、$のようなものは、私はchild_pagesテーブルを照会し、発見した= 60

を数えレコードのその95%は=「0」を処理しているので、LIMIT 1000

1000行を返すために、私のクエリを強制する方法はありに対応するレコードがたくさんあるのですか?

全クエリループ:

$start = "<div id=\"detailtable\">"; 
$stop = "</table></td></tr></table></div>"; 
$sql = "SELECT id,content FROM child_pages WHERE scanned='1' AND processed='0' LIMIT 1000"; 
$stmt = $db->query($sql); 
$new = 0; 
$lookedat = 0; 
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){ 
    $lookedat++; 
    $content = $row['content']; 
    $cid = $row['id']; 
    $mark1 = strpos($content,$start); 
    $mark2 = strpos($content,$stop); 
    //echo $mark1 . ", " . $mark2; 
    $segment = substr($content,$mark1, ($mark2 - $mark1) + strlen($stop)); 
    $doc = new simple_html_dom($segment); 
    if (! is_null($doc->find("div[id=detailtable]", 0))){ 
    $detailtable = $doc->find("div[id=detailtable]", 0); 
    if(count($detailtable) == 1){ 
     $e = $detailtable->children(); 
     $children = $e[0]->find('.data'); 
     $count = 0; 
     $insert['processed_thru']  = trim($children[0]->plaintext); 
     $insert['document_number_j'] = trim($children[1]->plaintext); 
     $insert['status']    = trim($children[2]->plaintext); 
     $insert['case_number']   = trim($children[3]->plaintext); 
     $insert['name_of_court']  = trim($children[4]->plaintext); 
     $insert['file_date']   = trim($children[5]->plaintext); 
     $insert['date_of_entry']  = trim($children[6]->plaintext); 
     $insert['expiration_date']  = trim($children[7]->plaintext); 
     $insert['amount_due']   = trim(str_replace("$","",$children[8]->plaintext)); 
     $insert['interest_rate']  = trim($children[9]->plaintext); 
     $insert['plaintiff']   = trim($children[10]->plaintext); 

     $insert['defendant'] = ""; 

     for($iii=11;$iii<count($children) ;$iii++){ 
      $insert['defendant'] .= trim($children[$iii]->plaintext); 
     } 

     if($insert['status'] !== "TERMINATED" && 
      strpos($insert['plaintiff'],"STATE OF FLORIDA") == false && 
      strpos($insert['plaintiff'],"DEPARTMENT OF REVENUE") == false && 
      strpos($insert['plaintiff'],"DEPARTMENT OF ENVIRONMENTAL PROTECTION") == false){ 

      //net elements here 

      /*echo "<pre>"; 
      print_r($insert);*/ 

      // table: cases2 columns: id,processed_thru,document_number_j,status,case_number,name_of_court,file_date,date_of_entry,expiration_date,amount_due,interest_rate,plaintiff,defendant 
      $colstring = "processed_thru,document_number_j,status,case_number,name_of_court,file_date,date_of_entry,expiration_date,amount_due,interest_rate,plaintiff,defendant"; 
      $prepareColString = ":processed_thru,:document_number_j,:status,:case_number,:name_of_court,:file_date,:date_of_entry,:expiration_date,:amount_due,:interest_rate,:plaintiff,:defendant"; 
      $table = "cases"; 

      foreach($insert as $k=>$v){ 
       ${"$k"} = trim(preg_replace('/\h+/', ' ', $v)); 
      } 

      $stmt2 = $db->prepare("INSERT INTO $table ($colstring) VALUES ($prepareColString)"); 
      $stmt2->bindParam(':document_number_j', $document_number_j); 
      $stmt2->bindParam(':processed_thru', $processed_thru); 
      $stmt2->bindParam(':status', $status); 
      $stmt2->bindParam(':case_number', $case_number); 
      $stmt2->bindParam(':name_of_court', $name_of_court); 
      $stmt2->bindParam(':file_date', $file_date); 
      $stmt2->bindParam(':date_of_entry', $date_of_entry); 
      $stmt2->bindParam(':expiration_date', $expiration_date); 
      $stmt2->bindParam(':amount_due', $amount_due); 
      $stmt2->bindParam(':interest_rate', $interest_rate); 
      $stmt2->bindParam(':plaintiff', $plaintiff); 
      $stmt2->bindParam(':defendant', $defendant); 
      $stmt2->execute(); 

      $new++; 
     } 
    } 
    } 
    $processed = 1; 
    $stmt3 = $db->prepare("UPDATE child_pages SET processed=:processed WHERE id=:id"); 
    $stmt3->bindParam(':id', $cid); 
    $stmt3->bindParam(':processed', $processed); 
    $stmt3->execute(); 
} 

アクセサリデータ:アクセサリデータを出力

RECORDS SCANNED : 60 

NEW CASE RECORDS : 8 

COMPUTATIONS IN ms : 422 
SYSTEM CALLS IN ms : 15 

Total execution time in seconds: 129.66131019592 

コード: (これらは、スクリプトの先頭に配置されている)

// At start of script 
$time_start = microtime(true); 
$rustart = getrusage(); 

function rutime($ru, $rus, $index) { 
    return ($ru["ru_$index.tv_sec"]*1000 + intval($ru["ru_$index.tv_usec"]/1000)) 
- ($rus["ru_$index.tv_sec"]*1000 + intval($rus["ru_$index.tv_usec"]/1000)); 
} 


echo "<p>RECORDS SCANNED : $lookedat </p>"; 
echo "<p>NEW CASE RECORDS : $new </p>"; 

$ru = getrusage(); 

echo "<p>COMPUTATIONS IN ms : " . rutime($ru, $rustart, "utime") . "</p>"; 
echo "SYSTEM CALLS IN ms : " . rutime($ru, $rustart, "stime") . "</p>"; 

// Anywhere else in the script 
echo '<p>Total execution time in seconds: ' . (microtime(true) - $time_start) . "</p>"; 
+0

おそらく正しい質問をしてください。クエリがなぜそんなに遅いのですか? –

+0

確かに、 'limit'を意味のあるものにするために何かを注文する必要があります。そして、 "私はchild_pagesテーブルを照会し、95%のレコードが処理されていることがわかりました= '0'、 - yes、そして何件が' processed = 0 AND scanned = 1'ですか?とにかく、whileループは何ですか?すべての関連コードを投稿してください。 –

+1

各ページ/行の処理時間はどのくらいですか?スクリプトは正常に実行されますか? –

答えて

1

の場合あなたの目標は1ページに1000行すべてを表示することで、部分ごとに読み込むことができます。ページを開くときにAJAXを使用してさらにスクロールすると100行のように表示されます。

第一部分

$sql = "SELECT id,content FROM child_pages WHERE scanned='1' AND processed='0' LIMIT 0,100"; 

第二部分

$sql = "SELECT id,content FROM child_pages WHERE scanned='1' AND processed='0' LIMIT 100,200"; 

等...

はそれが助け願っています。

+0

あなたの答えは私が検討している戦略の1つです。 – TARKUS

+1

上記のように、ORDER BYのないLIMITは無意味です。 – Strawberry

+1

これは見た目のUIパフォーマンスを助けるかもしれませんが、なぜスタンドアロン - 540が利用可能なときにクエリが60行しか返さないのかという疑問に答えることはできません。 –

関連する問題