我有这段代码:
if(($banners = $this->app->cache5min->get($key_cache)) === NULL) {
$find_items = array();
$banners = $this->app->db->fetchAll("
SELECT b.id,b.active, b.richmedia, b.rich_position, b.ip_limit,
b.cookie_limit, b.cookie_interval, b.day_limit, b.limit_interval,
b.frequency, b.close_btn, b.use_geo,
bpl.s_x, bpl.s_y
FROM bs_items_places AS bp
LEFT JOIN bs_items AS b ON b.id = bp.item_id
LEFT JOIN bs_places AS bpl ON bpl.id = bp.place_id
WHERE b.active = 1
AND b.date_start < '".$dateNow."'
AND b.date_stop > '".$dateNow."'
AND bpl.active = 1
AND bp.place_id = {$idpl}
AND (IF((time_from!='00:00:00' AND time_to!='00:00:00'),
(time_from<='".$dateTimeNow."'
AND time_to >='".$dateTimeNow."'), 1)
)
GROUP BY b.id
ORDER BY b.frequency DESC, b.day_limit DESC
");
foreach($banners AS $bnr) {
$find_items[$bnr['id']] = $bnr;
}
$banners = $find_items;
$this->app->cache5min->save($key_cache,$banners);
}
//echo '<pre>'; print_r($banners); exit;
if(!$banners || !count($banners)) { return $this->getDefaultBanner($idpl,$x); }
当我删除第一个语句时,我的CPU是好的,当我返回第一个语句时,我的CPU 100%并且这给了mysql进程,我如何优化选择查询?
答案 0 :(得分:0)
除非你需要,否则第一步是摆脱LEFT
。这可能会打开更多优化选项。
这个结构基本上是不可优化的:
WHERE start < ...
AND end > ...
有一个&#34;爆炸内爆&#34;问题。首先,由于JOINs
导致行数爆炸,然后它会对GROUP BY
进行内爆。但是......同时,没有&#34;聚合&#34;例如COUNT()
或SUM()
。所以这有点像一个形式不好的查询 - 为什么你需要做GROUP BY
?如果你得到重复&#39;行,然后你有一个更糟糕的问题 - 在没有重复的列中会发生什么?你会得到随机值。看看没有GROUP BY
会发生什么。
bp
上的此综合索引可以帮助:
INDEX(place_id, item_id)