[英]PHP - slow page load when looping results from MySQL database
我有PHP代碼,獲取從MySQL數據庫的結果-玩具的名稱(在toys
的表), users
和網頁玩具和獨特的用戶 ,並顯示計數 。
玩具的名稱可以是一個單詞或單詞的組合。 我們想從toys
獲取那些結果,這些toys
toys_text
字段具有words
表中所有單詞組合的words
(例如-如果words
表具有名為blue car
條目- blue
和car
都應出現在toys
表toys_text
字段中,比賽)。 隨着時間的推移,數據庫會隨着添加了用戶的新玩具和移除用戶的過時玩具而變化。
生成的頁面加載速度非常慢,在GT-metrix測試中耗時約10秒。 Google Analytics(分析)說我的代碼有問題。 我的代碼具有如下子查詢-
<?php
$WordQ = $db->query("SELECT * FROM words ORDER BY `words`.`words` ASC");
$i = 1;
while($row = $WordQ->fetch(PDO::FETCH_ASSOC)){
$Word = $row['words'];
$WordsArr = explode(" ", $row['words']);
$query = "";
if(count($WordsArr) > 1){
$query = "SELECT t_id,name,toys_text FROM toys WHERE toys_text
LIKE '%".implode("%' AND toys_text LIKE '%", $WordsArr)."%'";
}else{
$query = "SELECT t_id,name,toys_text FROM toys WHERE toys_text
LIKE '%$WordsArr[0]%'";
}
$countIds = array();
$countNames = array();
$Data = $db->query($query);
while($data = $Data->fetch(PDO::FETCH_ASSOC)){
$countIds[] = $data['t_id'];
$countNames[] = $data['name'];
}
?>
<tr>
<td><?php echo $i;?></td>
<td><?php echo $row['words'];?></td>
<td><a href="showtoys.php?word=<?php echo urlencode($Word); ?
>" target="_blank"><?php echo count(array_unique($countIds)); ?>
</a></td>
<td><a href="showtoys.php?word=<?php echo urlencode($Word); ?
>" target="_blank"><?php echo count(array_unique($countNames));
?></a></td>
</tr>
<?php $i++;} ?>
我試圖刪除子查詢,但是頁面加載緩慢。 請指導如何加快頁面加載速度。 以下是沒有子查詢的代碼-
<?php
$query = "SELECT * FROM words ORDER BY `words`.`words`
ASC";
$result = mysqli_query($con, $query);
$i = 1;
while($row = mysqli_fetch_array($result)){
$Word = $row['words'];
$WordsArr = explode(" ", $row['words']);
$query = "";
if(count($WordsArr) > 1){
$query1 = "select COUNT(*) as 'count', COUNT(DISTINCT
t.name) AS 'cnt' from toys t WHERE toys_text LIKE '%".implode("%' AND
toy_text LIKE '%", $WordsArr)."%'";
}else{
$query1 = "select COUNT(*) as 'count', COUNT(DISTINCT t.name) AS
'cnt' from toys t WHERE
toys_text LIKE '%$WordsArr[0]%'";
}
$Data1 = mysqli_query($con, $query1);
$total1 = mysqli_fetch_assoc($Data1);
?>
<tr>
<td><?php echo $i;?></td>
<td><?php echo $row['words'];?></td>
<td><a href="showtoys.php?word=<?php echo
urlencode($Word); ?>" target="_blank"><?php echo
$total1['count']; ?></a></td>
<td><a href="showtoys.php?keyword=<?php echo urlencode($Word);
?>" target="_blank"><?php echo $total1['cnt']; ?></a></td>
</tr>
<?php $i++;} ?>
這是我的MySQL表結構-
字詞:
S.No名稱類型
id Primary int(11)
單詞varchar(60)
例如-白色汽車,氣球,藍色巴士
輸入enum('words','phrase')
玩具 :
序號 名稱類型
t_id主要bigint(20)
toys_text FULLTEXT索引varchar(255)
user_id BTREE索引bigint(20)
名稱BTREE索引char(20)
Mysql是帶有InnoDB存儲的10.1.30-MariaDB。
編輯-
說我在words
桌上有個叫little blue car
玩具。 那么真正的比賽將是-我有一個little
car
是blue
。 我的little
car
的blue
顏色是非常快的。
錯誤的匹配將是-
我有一輛小汽車。 我的小車很好。
意思是所有單詞都應該出現在toys_text
字段中以實現真正的匹配。
我將查詢更改為
if(count($WordsArr) > 1){
$query1 = "select COUNT() as 'count',
COUNT(DISTINCT t.name) AS 'cnt' from toys t WHERE MATCH (toys_text) AGAINST
('".implode("'+'", ($WordsArr))."' IN BOOLEAN MODE)";
}else{
$query1 = "select COUNT() as 'count', COUNT(DISTINCT t.name) AS 'cnt' from
toys t WHERE MATCH (toys_text) AGAINST ('%$WordsArr[0]%')";
現在,對於具有大量計數的單詞和單詞組合,它的計數為0。 這些詞不在Mysql的非索引字表中。 這是FULLTEXT搜索的限制嗎?
我認為問題出在執行SQL請求的PHP循環中。 因此,為了減少時間,您不應該要求太多,而要嚴格執行最低要求。 在您的情況下,很難找到一種干凈的方法,但是應該有一種!
通過sql Substring函數,可以創建“玩具”表中所有單詞的視圖(一個一個地)。 然后,子查詢函數不是“ like”,而是一個簡單的“ =”,它要快得多。 https://mariadb.com/kb/zh/library/create-view/
我建議使用存儲過程來加快查詢速度,因為使用了while循環,然后在其中包含了另一個查詢。 如果只調用過程,則比在php中建立查詢要快。
嘗試檢查此鏈接以獲取參考: https : //dev.mysql.com/doc/refman/5.7/en/stored-routines.html
我向您保證,它將使查詢順利。
如果您只需要獲取包含單詞的那些玩具的數量,我建議您在使用Join的while循環之前僅在第一部分中查詢所有玩具,然后對它們進行計數並按單詞進行分組。
$stringWord= str_replace(' ', '%', $WordsArr);
$query1 = "call toysQuery(".$stringWord.")";
然后在您的過程參數中使用varchar。
您正在循環中從SQL語句的輸出生成和運行SQL。 只需在查詢之間進行連接,一次往返數據庫,一次循環以顯示結果。
正如@Sammitch所建議的那樣,在布爾模式下通過foreach循環使用MATCH()更改了查詢。 現在,該頁面將在第三次加載(大約3秒)后加載。
這是我的代碼-
<?php
$query = "SELECT * FROM words ORDER BY `words`.`words`
ASC";
$result = mysqli_query($con, $query);
$i = 1;
while($row = mysqli_fetch_array($result)){
$Word = $row['words'];
$WordsArr = explode(" ", $row['words']);
$query = "";
if(count($WordsArr) > 1){
foreach ($WordsArr as $value) {
$value1='';
$value1 .= " +"."(".$value."*".")";
}
$query1 = "select COUNT(*) as 'count', COUNT(DISTINCT
t.name) AS 'cnt' from toys t WHERE MATCH (toys_text) AGAINST
('$value1' IN BOOLEAN MODE)";
}else{
$query1 = "select COUNT(*) as 'count', COUNT(DISTINCT t.name) AS
'cnt' from toys t WHERE
MATCH (toys_text) AGAINST ('$WordsArr[0]* IN BOOLEAN MODE')";
}
$Data1 = mysqli_query($con, $query1);
$total1 = mysqli_fetch_assoc($Data1);
?>
<tr>
<td><?php echo $i;?></td>
<td><?php echo $row['words'];?></td>
<td><a href="showtoys.php?word=<?php echo
urlencode($Word); ?>" target="_blank"><?php echo
$total1['count']; ?></a></td>
<td><a href="showtoys.php?keyword=<?php echo urlencode($Word);
?>" target="_blank"><?php echo $total1['cnt']; ?></a></td>
</tr>
<?php $i++;} ?>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.