$order = isset($order) && in_array($order, array('credits','gender','username')) ? $order : '';代碼: member.php=90
switch($order) { case 'credits': $orderadd = "ORDER BY credits DESC"; break; case 'gender': $orderadd = "ORDER BY gender DESC"; break; case 'username': $orderadd = "ORDER BY username DESC"; break; default: $orderadd = 'ORDER BY uid'; $order = 'uid'; break; }點評: 統計選項->會員列表沒法根據註冊日期排序。
$order = isset($order) && in_array($order, array('credits','gender','username', 'regdate')) ? $order : '';line90修改成
switch($order) { case 'credits': $orderadd = "ORDER BY credits DESC"; break; case 'gender': $orderadd = "ORDER BY gender DESC"; break; case 'username': $orderadd = "ORDER BY username DESC"; break; case 'regdate': $orderadd = " ORDER BY regdate DESC"; break; // ADD default: $orderadd = 'ORDER BY uid'; $order = 'uid'; break; }
$query = $db->query("SELECT * FROM {$tablepre}threadtypes WHERE typeid IN ($typeids) AND special='' ORDER BY displayorder");點評: 牛頭不對馬嘴,special字段明明是int類型卻去搜索''空字符串,還好這個表不會大,否則坑死人不償命
$db->query("UPDATE {$tablepre}threads SET attachment='0' WHERE tid IN ($tids)".($attachtids ? " AND tid NOT IN ($attachtids)" : NULL));代碼: admin/attach.inc.php=176
$db->query("UPDATE {$tablepre}posts SET attachment='0' WHERE pid IN ($pids)".($attachpids ? " AND pid NOT IN ($attachpids)" : NULL));
---------------------------------------------------------------------------------------------
類型: 多餘操做
$query = $db->query("SELECT tid FROM {$tablepre}attachments WHERE tid IN ($tids) GROUP BY tid ORDER BY pid DESC");點評: 可以使用「SELECT DISTINCT」來替代「GROUP BY」,可「ORDER BY」是啥意思呢?相關操做對結果集順序並未有要求,多餘的排序操做將會耗費CPU能力與內存佔用,結果將增長數據庫負載。只不過通常一個主題不會有海量附件,因此性能降低不明顯。
do{ $query = $db->query("SELECT f.name AS forumname, f.allowsmilies, f.allowhtml, f.allowbbcode, f.allowimgcode, t.tid, t.fid, t.authorid, t.author, t.subject, t.views, t.replies, t.dateline, p.message, p.useip, p.attachment, p.htmlon, p.smileyoff, p.bbcodeoff, tm.uid AS moduid, tm.username AS modusername, tm.dateline AS moddateline, tm.action AS modaction FROM {$tablepre}threads t LEFT JOIN {$tablepre}posts p ON p.tid=t.tid AND p.first='1' LEFT JOIN {$tablepre}threadsmod tm ON tm.tid=t.tid LEFT JOIN {$tablepre}forums f ON f.fid=t.fid WHERE t.displayorder='-1' $sql GROUP BY t.tid ORDER BY t.dateline DESC LIMIT $ppp OFFSET ".(($pagetmp - 1) * $ppp)); $pagetmp--; } while(!$query->rowCount() && $pagetmp);點評: "GROUP BY t.tid"是多餘的,由於主表是threads tid是PK,上方line45還有一處相似。也許此段代碼的大哥喜歡作菜。可廚藝不精,不知道何時該放什麼調料,因而手邊的調料瓶就都拿起來倒兩下,只要味道不難吃這菜就算完成了。寫代碼也如此,估摸着寫着寫着突然想起SQL還有「GROUP BY」的功能,隨手拈來搗入SQL中攪和攪和,結果正確味道正好。遂頓悟,不會作菜的廚子不是個好程序猿 :D
$query = $db->query("SELECT author, COUNT(*) AS posts FROM {$tablepre}posts WHERE dateline>='$timestamp'-86400 AND invisible='0' AND authorid>'0' GROUP BY author ORDER BY posts DESC LIMIT 1");點評: 「AND authorid>'0'」 條件能夠刪除掉。這個條件毫無心義,只會讓數據庫在抓取row時過濾條件多一個結果卻沒差異。
$query = $db->query("SELECT t.tid,t.fid,t.readperm,t.author,t.authorid,t.subject,t.dateline,t.lastpost,t.lastposter,t.views,t.replies,t.highlight,t.digest,t.typeid,t.sortid $sqlfrom WHERE t.readperm='0' $sql AND t.displayorder>='0' AND t.fid>'0' <-------- $attachadd ORDER BY t.$orderby DESC LIMIT $items OFFSET $startrow " );
extract($db->fetch_first("SELECT COUNT(*) AS threadcount, SUM(t.replies)+COUNT(*) AS replycount FROM {$tablepre}threads t, {$tablepre}forums f WHERE f.fid='$fid' AND t.fid=f.fid AND t.displayorder>='0'"));點評: 其實沒用到forums表的數據,對forums表的鏈接徹底是多餘的
extract($db->fetch_first("SELECT COUNT(*) AS threadcount, SUM(replies)+COUNT(*) AS replycount FROM {$tablepre}threads WHERE fid='$fid' AND displayorder>='0'"));
$queryt = $db->query("SELECT uid FROM {$tablepre}members LIMIT $current, $pertask");點評: 查詢時SQL不嚴格未使用ORDER BY,致使結果集、結果順序不肯定。此頁面多個SQL均存在這個問題, 會致使分頁結果不可預料,尤爲是提取帖子(精華)分頁時!
$queryt = $db->query("SELECT uid FROM {$tablepre}members ORDER BY uid LIMIT $current, $pertask");
$specialadd2 .= "AND (dp.stand='0' OR dp.stand IS NULL OR p.first='1')";代碼: viewthread.php=378
$thread['replies'] = $sdb->result_first("SELECT COUNT(*) FROM {$tablepre}posts p LEFT JOIN {$tablepre}debateposts dp ON p.pid=dp.pid WHERE p.tid='$tid' AND (dp.stand='0' OR dp.stand IS NULL)");代碼: include/task.func.php=134
$nextnewbietaskid = intval($db->result_first("SELECT t.taskid FROM {$tablepre}tasks t LEFT JOIN {$tablepre}mytasks mt ON mt.taskid=t.taskid AND mt.uid='$discuz_uid' WHERE mt.taskid IS NULL AND t.available='2' AND t.newbietask='1' ORDER BY t.newbietask DESC LIMIT 1"));
點評: 會數據庫的應該知道NULL值不會走索引,除非創建ISNULL索引,做NULL查詢將會掃全表致使性能暴跌! DZ數據庫建表風格是都採用NOT NULL約束,PHP代碼風格也是不作NULL的判斷。在字段已經明確NOT NULL約束條件下還採用(dp.stand='0' OR dp.stand IS NULL)這樣條件,對mt.taskid不使用mt.taskid>0判斷,若是不是臨時工乾的那就基本上是存心考古的…… php
FIX: include/task.func.php=134不能簡單刪除 ISNULL判斷,不然將致使新手任務沒法結束,把 mt.taskid IS NULL 改爲 mt.taskid = 0 便可html
$uids = 0;代碼: admin/prune.inc.php~220
$forums = '0';代碼: admin/prune.inc.php~230
$uids = '-1';代碼: viewthreads.php~220
$attachpids = -1;代碼: topicadmin.php~102 前臺刪除帖子
$pids = 0;代碼: topicadmin.php~109 前臺刪除帖子
$pids .= ','.$post['pid'];代碼: admin/threads.inc.php~622
$tids = 0;代碼: admin/forums.inc.php~1289
$query = $db->query("SELECT * FROM {$tablepre}threadtypes WHERE typeid IN ($typeids) AND special='' ORDER BY displayorder");代碼: modcp/moderate.inc.php~286
WHERE pid IN (0,".implode(',', $pidarray).")");代碼: admin/moderate.inc.php=727
$db->query("UPDATE {$tablepre}posts SET invisible='0' WHERE pid IN (0,".implode(',', $pidarray).")");代碼: include/misc.func.php~289
$db->query("UPDATE $tablepre$table SET $viewscol=$viewscol+'$views' WHERE $idcol IN (0$ids)" );代碼:
$str = $comma = ''; foreach (..) { $str .= $comma. 'something'; $comma = ','; }
$forumstickycount = $stickycount = $stickytids = 0;點評: 對tid搜索包含0, 版塊精華SQL相似以下,將會致使掃全索引. 而且影響到即便沒有全局置頂主題也會作一樣查詢,很是坑爹
SELECT t.* FROM cdb_threads t WHERE t.tid IN (0,110) AND t.displayorder IN (2, 3, 4) ORDER BY displayorder DESC, lastpost DESC LIMIT 1 OFFSET 0
if(($start_limit && $start_limit > $stickycount) || !$stickycount || $filterbool) {
以前加上過濾mysql
if ($stickytids) { $tarr = array(); $stickytids = explode(',', $stickytids); foreach ($stickytids as $s_id) { $s_id = intval($s_id) && $s_id > 0 && $tarr[] = $s_id; } $stickytids = implode(',', $tarr); unset($tarr); } else { $stickytids = ''; }
$querysticky = $sdb->query("SELECT t.* FROM {$tablepre}threads t WHERE t.tid IN ($stickytids) AND t.displayorder IN (2, 3, 4) ORDER BY displayorder DESC, $orderby $ascdesc LIMIT $start_limit, ".($stickycount - $start_limit < $tpp ? $stickycount - $start_limit : $tpp));修改爲:
if ($stickytids) { $querysticky = $sdb->query("SELECT t.* FROM {$tablepre}threads t WHERE t.tid IN ($stickytids) AND t.displayorder IN (2, 3, 4) ORDER BY displayorder DESC, $orderby $ascdesc LIMIT ".($stickycount - $start_limit < $tpp ? $stickycount - $start_limit : $tpp). ' OFFSET '. $start_limit); } else { $querysticky = false; }
---------------------------------------------------------------------------------------------
類型: 多餘鏈接
坑爹指數: ★★★
代碼: include/requres.func.php~450程序員
case 'weekposts': $week = gmdate('w', $timestamp) - 1; $week = $week != -1 ? $week : 6; $historytime = mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp) - $week, date('Y', $timestamp)); $sql = "SELECT DISTINCT (p.author) AS username,p.authorid AS uid,COUNT(p.pid) AS postnum FROM {$tablepre}posts p LEFT JOIN {$tablepre}memberfields mf ON mf.uid = p.authorid WHERE p.dateline>=$historytime GROUP BY p.authorid, p.author ORDER BY postnum DESC";
點評: 輸出字段並未使用memberfields表中字段,貌似MySQL在這種狀況下並不會所以而放棄鏈接操做,對此表的鏈接徒耗資源。
sql
---------------------------------------------------------------------------------------------
類型: 邏輯錯誤
坑爹指數: ★
代碼: admin/recyclebin.inc.php~145數據庫
$threadcount = $db->result_first("SELECT count(*) FROM {$tablepre}threads t LEFT JOIN {$tablepre}threadsmod tm ON tm.tid=t.tid WHERE t.displayorder='-1' $sql");
點評: 此SQL未對threadsmod做以下do while()循環中相似的GROUP BY處理,若是一個回收站中主題被反覆刪除恢復那麼就會出現「符合條件的回收站主題數」不爲0但下方無列表顯示這種狀況
FIX1: 添加一條GROUP BY語句過濾threadsmod的結果。但限於MySQL不標準的GROUP BY語法,其結果(順序)也許非正確數組
$threadcount = $db->result_first("SELECT count(*) FROM {$tablepre}threads t LEFT JOIN {$tablepre}threadsmod tm ON tm.tid=t.tid GROUP BY tm.tid ORDER BY tm.dateline DESC, t.dateline DESC WHERE t.displayorder='-1' $sql");
版權曾經擁有,歡迎網上分享
轉載請保留連接 http://my.oschina.net/u/126398/blog/39255緩存