我正在使用codeigniter和mysql并应用于具有200 MB内存和1 GB CPU的服务器中,获得了40.000行 表a(index:idx_cat)和44行(index:primary)在类别中,我需要在每个类别中获得前4个,这是我的查询
SELECT id,title,preview,created,image,dummy,name
FROM
(
select news.id AS id,news.title AS title,preview,created,news.image,category_id ,
@num := if(@cat = category_id, @num + 1, 1) as row_number,
@cat := category_id as dummy,
name,d_order
from news use index (idx_cat) inner join category b on category_id=b.id
where
news.category_id in (9,8,3,35,57,56,15,58,41,42,43,44,34,52,37,38,36,11) and
news.status = 1
having row_number <= 4
order by dummy ASC,news.created desc
) as a
order by d_order ASC,created DESC
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL **29639** Using filesort
2 DERIVED b ALL PRIMARY,id NULL NULL NULL **44** Using where; Using temporary; Using filesort
2 DERIVED news ref idx_cat idx_cat **4** b.id 846 Using where
并获得了其他6个简单的连接,如
select id,name from others a inner join b on a.cat_id = b.id
网站加载速度相当快,大约是1s或2s,但是如果在另一个标签中打开,那么加载它的位就像5-7s一样慢。
奇怪的是cpu使用率达到100%,内存使用量达到+ _ 40 MB完成一个视图(我确定没有其他打开)但CI PROFILING它只说用户4MB。
我还有按需加载模型,助手和库,只有两个(网址和表单)放在自动加载文件中。
如果我打开5到10个窗口它会说内存不足,请问你们有什么建议这件事会发生什么事情,这会让我发疯 - -
答案 0 :(得分:2)
要缩小内部选择结果的大小,请将字段name
和d_order
的选择和连接移动到外部选择
SELECT id,title,preview,created,image,dummy,name,d_order FROM
(
select news.id AS id,news.title AS title,preview,created,news.image,category_id ,
@num := if(@cat = category_id, @num + 1, 1) as row_number,
@cat := category_id as dummy
from news use index (idx_cat)
where
news.category_id in (9,8,3,35,57,56,15,58,41,42,43,44,34,52,37,38,36,11) and
news.status = 1
having row_number <= 4
order by dummy ASC,news.created desc
) as a inner join category b on category_id=b.id
order by d_order ASC,created DESC
可疑的是,行数仍然很大,但我们减少了内存。您选择的方式需要处理整个新闻表,然后以非常昂贵的计算删除不需要的行。如果你只使用news.id,cat.id和minimun字段进行新闻预选,可能会更有效率,所以新闻机构的重字段不在重选之中。
SELECT id,c.title,c.preview,created,c.image,dummy,name,d_order FROM
(
select news.id AS id,category_id ,
@num := if(@cat = category_id, @num + 1, 1) as row_number,
@cat := category_id as dummy
from news use index (idx_cat)
where
news.category_id in (9,8,3,35,57,56,15,58,41,42,43,44,34,52,37,38,36,11) and
news.status = 1
having row_number <= 4
order by dummy ASC,news.created desc
) as a
inner join category b on category_id=b.id
inner join news c on a.id = c.id
order by d_order ASC,created DESC
可能我有一些sintax错误,但在这里写一点有点困难,我没有要测试的数据。希望你能明白这个问题。