php - 如何保证从 SELECT 查询中获取 1000 行? MySQL

标签 php mysql

带有指导如何使用 LIMIT 的答案的问题并不适合我的情况,但可能是我误解了 LIMIT 的局限性和缺陷。或者,也许我的查询是错误的,这使得这个问题合法。

我有一个名为“child_pages”的表,其中包含一个名为“url”的字段,其值是应该抓取的网址。抓取属于该 url 的页面后,生成的内容 html 将存储在名为“content”的字段中。 child_pages 表有 200,000 条记录。

该表还有一个“已扫描”和“已处理”字段,它们都是tinyint,所以我可以说“1”=是,该行已被扫描,而“1”=该行已被处理。

我将一个脚本设置为本地服务(Windows),该脚本将读取 child_pages 表并从 url 字段读取值,然后执行抓取,最后将生成的 html 存储到内容字段中。完成此操作后,“已扫描”字段将标记为“1”。

现在另一个脚本也单独运行,该脚本查询 child_pages 表,查找所有已扫描='1'但已处理='0'的记录。从该结果集中,我将从未处理的记录中读取内容字段的 html 值,最后对我从“内容”字段 html 中提取的数据进行一些处理。

这是我的查询:

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

我注意到处理速度非常慢。我每五秒处理 1 到几条记录。我想,当我一次选择 1000 行时,怎么可能呢?

所以我在 while 循环内输出了一个循环计数器,我发现它没有返回 $counted = 1000,而是返回 $counted = 60 之类的东西。

我查询了child_pages表,发现95%的记录都被processed='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>";

最佳答案

如果您的目标是在一页中显示所有 1000 行,也许您可​​以按部分加载它。当页面打开时显示 100 行,当使用 AJAX 向下滚动时加载更多。

第一部分

$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";

等等...

希望有帮助。

关于php - 如何保证从 SELECT 查询中获取 1000 行? MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38146143/

相关文章:

php - 如何从字符串中删除扩展名(只有真正的扩展名!)

php - 从不同表插入时自动增量重叠

php - PHP函数中的奇怪过滤器结果

mysql - 在数据库之间移动表

php - 在MYSQL中放置数组的值

php - Apple Sign In "invalid_client",使用 PHP 和 openSSL 签署 JWT 进行身份验证

php - 改变 symfony 中的数据库( Doctrine )

php - 尝试从多维数组中提取值以在 SQL 语句中使用

mysql - 如何在 MySQL 中进行分组排名

javascript - 使用 php 和 javascript 进行 AJAX 即时检查