[英]single query for multiple sql queries
我正在開發一個項目,用戶可以在其中添加評論,也可以點擊任何帖子。
現在,我必須顯示評論總數和點擊總數,還必須顯示用戶是否已經點擊了該帖子。
因此,基本上,我需要為此操作執行三個sql查詢:
我想知道是否有可能將這三個SQL查詢減少為一個並減少數據庫負載?
任何幫助表示贊賞。
$checkifrated=mysql_query("select id from fk_views where (onid='$postid' and hit='hit' and email='$email')");//counting hits
$checkiffollowing=mysql_query("select id from fk_views where (onid='$postid' and hit='hit' and email='$email')");
$hitcheck=mysql_num_rows($checkifrated);//checking if already hited or not
$checkifrated=mysql_query("select id from fk_views where (onid='$postid' and comment !='' and email='$email')");//counting comments
該查詢返回命中數和非空注釋數。
select ifnull(sum(hit='hit'),0) as hits, ifnull(sum(comment !=''),0) as comments
from fk_views where onid='$postid' and email='$email'
根據您提供的查詢,我認為您是否需要分別查詢他是否被點擊,只需在您的代碼中檢查點擊數是否大於0
是的,可以將三個查詢合並為一個查詢。 這可能會(也可能不會)“減少數據庫負載”。 這里的關鍵是制定有效的執行計划,該計划主要取決於合適索引的可用性。
將三個低效率的查詢合並為一個查詢不會神奇地提高查詢的效率。 關鍵是使每個查詢盡可能高效。
如果每個查詢正在處理同一表中的行,則可能有一個SELECT語句處理整個集合,以獲得指定的結果。 但是,如果每個查詢都引用一個不同的表,則最有效的方法可能是將它們與UNION ALL集運算符組合在一起。
缺少架構定義,當前正在使用的查詢以及每個查詢的EXPLAIN輸出,嘗試為您提供可用的建議是不切實際的。
更新
根據問題的更新,提供示例查詢...我們注意到其中兩個查詢似乎是相同的。
使查詢返回COUNT()
聚合要比將所有單個行都拉回客戶端並在客戶端上對它們進行計數要有效得多,例如
SELECT COUNT(1) AS count_hits
FROM fk_views v
WHERE v.onid = '42'
AND v.hit = 'hit'
AND v.email = 'someone@email.address'
為了結合三個查詢的處理,我們可以在SELECT列表中使用條件表達式。 例如,我們可以在WHERE子句中的onid
和email
列上使用相等謂詞,並使用表達式對hit
列進行檢查...例如:
SELECT SUM(IF(v.hit='hit',1,0)) AS count_hits
, SUM(1) AS count_all
FROM fk_views v
WHERE v.onid = '42'
AND v.email='someone@email.address'
組合三個獨立查詢的“技巧”將是使用一組通用的相等謂詞(在所有三個查詢中都匹配的WHERE子句部分)。
SELECT SUM(IF(v.hit='hit' ,1,0)) AS count_hits
, SUM(IF(v.comment!='',1,0)) AS count_comments
, SUM(1) AS count_all
FROM fk_views v
WHERE v.onid = '42'
AND v.email ='someone@email.address'
如果我們要堅持使用不推薦使用的mysql接口(通過PDO或mysqli),那么使用mysql_real_escape_string
函數以避免SQL注入漏洞很重要。
$sql = "SELECT SUM(IF(v.hit='hit' ,1,0)) AS count_hits
, SUM(IF(v.comment!='',1,0)) AS count_comments
, SUM(1) AS count_all
FROM fk_views v
WHERE v.onid = '" . mysql_real_escape_string($postid) . "'
AND v.email = '" . mysql_real_escape_string($email) ;
# for debugging
#echo $sql
$result=mysql_query($sql);
if (!$result) die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
echo $row['count_hits'];
echo $row['count_comments'];
}
為了提高性能,我們可能希望索引包含onid
和email
的前onid
列,例如
... ON fk_views (onid,email)
EXPLAIN
的輸出將顯示執行計划。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.