2012-11-18 2 views
3

codeigniter와 mysql을 사용하고 200MB 메모리와 1GB CPU가있는 서버에 적용하여 테이블에 40.000 개의 행이 있고 (index : idx_cat) 44 행 (인덱스 : 기본)에 카테고리와 나는, 6 간단한codeigniter, mysql 질의 성능 문제

select id,name from others a inner join b on a.cat_id = b.id 

이 사이트는 매우 빠른 약 1 초 또는 2 초 최고로드처럼 가입 여기 내 쿼리

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  

의 각 카테고리에 다음의 4 위에 얻을 필요가 및 기타 얻었다 하지만 다른 탭에서 열리는 동안 느리게 비트를로드하는 동안 5-7s.

이상한 점은 CPU 사용량이 도달 범위 100 %이고 메모리 사용량이 하나의보기를 완료하는 데 + 40MB를 얻었으나 다른 사용자가 열지는 않았지만 CI 프로 파일링은 사용자 4MB라고합니다.

나는 또한 자동로드 파일에 넣은 두 가지 (URL 및 양식) 요청시로드 모델, 도우미 및 라이브러리를 보유하고 있습니다. 나는 그것이 메모리가 말하는 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 –