Php 优化准备语句查询
我正试图从数据库中提取数据进行搜索。我尝试使用联接,但结果需要40秒才能显示。我还尝试将我的查询一分为二,由于嵌套的预处理语句存在问题,这也不起作用。如何优化联接查询?我将查询拆分以加快流程的做法正确吗?如果是这样,为什么嵌套循环不起作用 使用联接进行查询-Php 优化准备语句查询,php,mysql,prepared-statement,Php,Mysql,Prepared Statement,我正试图从数据库中提取数据进行搜索。我尝试使用联接,但结果需要40秒才能显示。我还尝试将我的查询一分为二,由于嵌套的预处理语句存在问题,这也不起作用。如何优化联接查询?我将查询拆分以加快流程的做法正确吗?如果是这样,为什么嵌套循环不起作用 使用联接进行查询- SELECT pdf.pdf_ID , pdf.absolute_path , sentance.sen_value , sentance.pdf_ID FROM pdf JOIN sentance
SELECT pdf.pdf_ID
, pdf.absolute_path
, sentance.sen_value
, sentance.pdf_ID
FROM pdf
JOIN sentance
ON sentance.pdf_ID = pdf.pdf_ID
WHERE pdf.absolute_path LIKE ?
AND sentance.sen_value LIKE ?
LIMIT ?,?
拆分查询-
第1部—
SELECT pdf.absolute_path
, pdf.pdf_ID
FROM pdf
WHERE pdf.absolute_path like "Data|Digital%"
ORDER
BY pdf.pdf_ID
第2部—
SELECT sentance.sen_value
FROM sentance
WHERE sentance.pdf_ID = 24159
and sentance.sen_value like "%John%"
LIMIT ?,?
由于准备好了语句,带有拆分查询的PHP无法工作
function getQueryResultCategory($pageNumber,$itemsPerPage,$word,$path){
$pdfIDList=array();
//$query="Select pdf.pdf_ID, pdf.absolute_path, sentance.pdf_ID, sentance.sen_value from pdf INNER JOIN sentance ON sentance.pdf_ID = pdf.pdf_ID WHERE sentance.sen_value LIKE ? LIMIT ?,? ODER BY pdf.pdf_ID";
//if we break this query into two parts
$getPDFsQuery="
SELECT absolute_path
, pdf_ID
FROM pdf
WHERE absolute_path LIKE ?
Order
BY pdf_ID";
$getResults="
SELECT sen_value
FROM sentance
WHERE pdf_ID = ?
and sen_value LIKE ?
LIMIT ?,?";
$searchTerm = "%".$word."%";
$path = $path."%";
$page_position = (($pageNumber-1) * $itemsPerPage);
include('Resources/Connections/localHost.php');
if (mysqli_connect_errno($con)){
echo "Failed to connect to MySQL: " . mysqli_connect_error();
mysqli_close($con);
}else if($partOne = $con->prepare($getPDFsQuery) or die(mysqli_error($con))){
$partOne->bind_param('s', $path);
$partOne->execute();
$partOne->store_result();
$partOne->bind_result($pathski,$pdfID);
if($partOne->num_rows < 1){
echo "no Results found in category ".$pathski;
mysqli_close($con);
$partOne->close();
//now that we have the pdf ids where the path matches we need to search these for the phrase
}else{
//put the pdf paths into an array so I can go through them and call queries on them
while($partOne-> fetch()){
echo "PDF File: ".$pathski."<br />";
echo $getResults."<br />";
echo $pdfID."<br />";
echo $searchTerm."<br />";
echo $page_position."<br />";
echo $itemsPerPage."<br />";
//we need to execute a query for each of the PDFs that match the category. AKA run that pdf id through aniother query.
if($partTwo = $con->prepare($getResults) or die(mysqli_error($con))){
$partTwo->bind_param('isii', $pdfID,$searchTerm,$page_position,$itemsPerPage);
$partTwo->execute();
$partTwo->store_result();
$partTwo->bind_result($sentance);
if($partTwo->num_rows < 1){
echo "no search term found in PDF".$pathski."<br />";
mysqli_close($con);
$partTwo->close();
//now that we have the pdf ids where the path matches we need to search these for the phrase
}else{
/*
while($partTwo->fetch()){
$occuranceCount;
$pathStack = array();
$current;
$current=$pdfID;
if(end($pathStack)!=$current){
$occuranceCount=0;
$current="";
$current=$pdfID;
array_push($pathStack,$current);
}else{
array_push($pathStack,$current);
$occuranceCount++;
}
$pathski= str_replace('|','/',$pathski);
$pathski= str_replace(' ','_',$pathski);
//we need to get the word from the sentance and wrap it in a sapn
$startPOS;
if(preg_match ('/'.$word.'/i', $sentance, $matches, PREG_OFFSET_CAPTURE)){
$indexOpen = $matches[0][1];
}
//need to add logic if search word is first word in sentance add span to beginning of sentance
$openTagPOS=$indexOpen;
if($openTagPOS<=0){
$openTagPOS=0;
$sentance = substr_replace($sentance, "<span class='highlight'>", $openTagPOS, 0);
if(preg_match ('/'.$word.'/i', $sentance, $matches, PREG_OFFSET_CAPTURE)){
$indexClose = $matches[0][1];
$indexClose=strlen($word)+$indexClose;
$sentance = substr_replace($sentance, "</span>", $indexClose, 0);
}
}else{
$sentance = substr_replace($sentance, "<span class='highlight'>", $openTagPOS, 0);
if(preg_match ('/'.$word.'/i', $sentance, $matches, PREG_OFFSET_CAPTURE)){
$indexClose = $matches[0][1];
}
$closingTagPOS=$indexClose+strlen($word);
$sentance = substr_replace($sentance, "</span>", $closingTagPOS, 0);
}
echo "<div class='result'>";
if(isset($_SESSION['browser']) && $_SESSION['browser']=="Chrome"){
echo "<p class ='path'>File: <a href='http://www.digifind-it.com/Parkway/pdfJS/pdfViewer/web/viewer.html?file=../../../".$pathski."&search=".$word."&occurance=".$occuranceCount."' target='blank'>".basename($pathski)."</a></p>";
}else if(isset($_SESSION['browser']) && $_SESSION['browser']!="Chrome"){
echo "<p class ='path'>File: <a href='http://www.digifind-it.com/Parkway/".$pathski."#search=\"".$word."\"' target='blank'>".basename($pathski)."</a></p>";
}
echo "<p class ='context'> context: ".$sentance."</p><br>";
echo "<p class ='context'> occurance num: ".$occuranceCount."</p><br>";
echo"</div>";
}
*/
}
}
}
echo "<div align='center'>";
echo paginate_function($itemsPerPage, $_SESSION['pagenumber']);
echo "</div>";
}
}
函数getQueryResultCategory($pageNumber、$itemsPerPage、$word、$path){
$pdfIDList=array();
//$query=“从sentance.pdf\u ID=pdf.pdf\u ID中的pdf内部连接sentance中选择pdf.pdf\u ID、pdf.absolute\u path、sentance.pdf\u ID、sentance.senu值,其中sentance.senu值如?LIMIT?、按pdf.pdf\u ID排序”;
//如果我们把这个查询分成两部分
$getPDFsQuery=”
选择绝对路径
,pdf\u-ID
从pdf
你的路在哪里?
顺序
按pdf_ID“;
$getResults=”
选择sen_值
从哨兵
其中pdf_ID=?
你的价值观是什么?
极限?,?“;
$searchTerm=“%”“$word.”%”;
$path=$path.“%”;
$page_position=($pageNumber-1)*$itemsPerPage);
包括('Resources/Connections/localHost.php');
if(mysqli\u connect\u errno($con)){
echo“未能连接到MySQL:”.mysqli_connect_error();
mysqli_close($con);
}否则如果($partOne=$con->prepare($getPDFsQuery)或die(mysqli_错误($con))){
$partOne->bind_参数('s',$path);
$partOne->execute();
$partOne->store_result();
$partOne->bind_结果($pathski,$pdfID);
如果($partOne->num_rows<1){
echo“在类别中未找到结果”。$pathski;
mysqli_close($con);
$partOne->close();
//现在我们有了路径匹配的pdf ID,我们需要在这些ID中搜索短语
}否则{
//将pdf路径放入一个数组中,这样我就可以遍历它们并调用对它们的查询
而($partOne->fetch()){
echo“PDF文件:.$pathski.”; echo$getResults。“
”; echo$pdfID.“
”; echo$searchTerm.“
”; 回显$page_位置。“
”; echo$itemsPerPage.“
”; //我们需要对与类别匹配的每个pdf执行一个查询。也就是说,通过另一个查询运行该pdf id。 如果($partTwo=$con->prepare($getResults)或die(mysqli_error($con))){ $partTwo->bind_参数('isii',$pdfID,$searchTerm,$page_position,$itemsPerPage); $partTwo->execute(); $partTwo->store_result(); $partTwo->bind_结果($sentance); 如果($partTwo->num_行<1){ echo“在PDF中找不到搜索词”。$pathski。“
”; mysqli_close($con); $partTwo->close(); //现在我们有了路径匹配的pdf ID,我们需要在这些ID中搜索短语 }否则{ /* 而($partTwo->fetch()){ $occuranceCount; $pathStack=array(); $current; $current=$pdfID; 如果(结束($pathStack)!=$current){ $occuranceCount=0; $current=“”; $current=$pdfID; 阵列推送($pathStack,$current); }否则{ 阵列推送($pathStack,$current); $occuranceCount++; } $pathski=str|u replace(“|”)、“/”、$pathski); $pathski=str_替换(“”,''''u',$pathski); //我们需要从句子中得到这个词,然后用sapn把它包起来 $startPOS; if(预匹配('/'.$word.'/i',$sentance,$matches,预偏移捕获)){ $indexOpen=$matches[0][1]; } //若搜索词是句子中的第一个词,则需要添加逻辑,并将跨度添加到句子的开头 $openTagPOS=$indexOpen;
如果($openTagPOS,请确保您的句子和PDF表格都在PDF\u ID上编制索引
不过,您的主要问题是WHERE子句中的类似内容。这些内容的性能不好,尤其是在开头有通配符的情况下。请参阅:否决投票的原因是什么?它正确地回答了原始海报的问题“如何优化加入查询?”我没有投反对票。我只是把它投了0票。所以你是说句子表中的主键需要是pdf\u ID?我是否应该设置一个像sen\u ID这样的唯一主键,然后使用pdf\u ID作为外键?@TimHunt,我不知道是谁投了反对票-我的问题是“它可能与谁有关”:我不是说句子表上的主键必须是pdf_ID,但是句子表应该在该列上有一个索引;这将提高连接性能。如果所有句子记录都必须属于pdf记录,将其作为pdf表的外键也是一个好主意。