2012-11-18 66 views
3

我正在使用codeigniter和mysql并应用于具有200 MB内存和1 GB CPU的服务器,在 表中获得40.000行(index:idx_cat)和44行(index:primary)类别和我需要得到最高的,然后4在每个类别中,这是我的查询codeigniter,mysql查询性能问题

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 

该网站加载相当快大约1秒或2秒之上,但如果在另一个选项卡中打开,而加载它的速度慢一点5-7s。

奇怪的是,CPU使用率达到100%,内存使用得到了+ _ 40 MB来完成一个视图(确定没有其他打开),但CI概要其只是用户4MB。

我也有加载模型,助手,和图书馆点播只是两个(网址和形式),我把自动载入文件。

如果我开那么5到10个窗口它说出来的内存,有你们这个东西是什么发生任何建议,这是推动我疯了-_-

回答

2

为了减轻内心的选择的结果的大小,移动选择和领域named_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 

Problably行的数量仍然很大,但我们已经降低了内存。您选择的方式需要处理整个新闻表格,然后以非常昂贵的计算方式删除不需要的行。如果你只是用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错误,但在这里写入有点困难,我没有数据来测试。希望你明白我发现问题的地步。

+0

很久没有互联网了,我有这个,它的工作原理非常感谢:D –