2009-10-23 5 views
7

450000 행의 뉴스가 가득한 테이블이 있습니다. 테이블 스키마는 다음과 같이이다 :Mysql 인덱스 구성

CREATE TABLE IF NOT EXISTS `news` (
    `id` int(11) NOT NULL auto_increment, 
    `cat_id` int(11) NOT NULL, 
    `title` tinytext NOT NULL, 
    `content` text NOT NULL, 
    `date` int(11) NOT NULL, 
    `readcount` int(11) NOT NULL default '0', 
    PRIMARY KEY (`id`), 
    KEY `cat_id` (`cat_id`), 
    KEY `cat_id_2` (`cat_id`,`id`), 
    KEY `cat_id_date` (`cat_id`,`date`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin5 AUTO_INCREMENT=462679 ; 

x가 100 이상이면 내가 카테고리 페이지는 15 초 이상 소요 "X"페이지에 대한 소식을 다음과 같은 SQL 명령을 실행할 때 :

:
select * news where cat_id='4' order by id desc limit 150000,10; 

내가이 같은 더 간단한 SQL 쿼리를 확인이 질문을 작성하고 또한 분에 가까이 갔다하지만 그것 "여기서"인덱스 "cat_id_2"

를 사용하여 해당 프로그램을 설명

select * from haberler order by id desc limit 40000,10; 

는 SQL이 걸리는 일을 다음과 같은 몇 밀리 초 같은 경우 :

select * from haberler order by id desc limit 20,10; 

내 my.cnf의 구성은 다음과 같이이다 :

skip-locking 
skip-innodb 
query_cache_limit=1M 
query_cache_size=256M 
query_cache_type=1 
max_connections=30 
interactive_timeout=600000 
#wait_timeout=5 
#connect_timeout=5 
thread_cache_size=384 
key_buffer=256M 
join_buffer=4M 
max_allowed_packet=16M 
table_cache=1024 
record_buffer=1M 
sort_buffer_size=64M 
read_buffer_size=16M 
max_connect_errors=10 
# Try number of CPU's*2 for thread_concurrency 
thread_concurrency=2 
myisam_sort_buffer_size=128M 
long_query_time   = 1 
log_slow_queries  = /var/log/mysql/mysql-slow.log 
max_heap_table_size=512M 

웹 사이트는 core2duo에서 실행 2GB RAM. 이 문제는 sort_buffer_size에 의해 발생할 수 있다고 생각하지만 확실하지 않습니다. 사전에 감사합니다.

+0

은 또한 당신의 인덱스 수 있을까,이 측면을 조사했다? –

+0

질문에 여러 가지 불일치가 있습니다. 더 명확하게 편집 할 수 있습니까? –

+0

그것은 지금 고쳐야한다, 테이블에 사용 된 이름은 원래 turkish이었다, 나는 그들 중 일부를 영어로 번역하는 것을 잊어 버린 것처럼 보인다. 어쨌든 내 나쁜 영어를 유감스럽게 생각합니다. – intacto

답변

17

업데이트 :

문제의 자세한 분석을 위해 내 블로그에서이 문서를 참조하십시오


당신이 LIMIT 150000, 10 같은 것을 발행, MySQL이이 트래버스해야 함을 의미합니다. 150,000 기록하고 다음을 찾으십시오 10.

색인 통과는 MySQL에서 느립니다.

또한 MySQL은 후기 행 조회를 수행 할 수 없습니다. 당신이 ORDER BY id LIMIT 100000, 10을 할 경우

이론적으로, 그 다음, 100000에서 100010에 값을 찾기 위해 인덱스를 사용하는 인덱스 것을 만족을 반환에만 10 행을 찾아 볼 충분하다.

MySQL을 제외한 모든 주요 시스템은이 값을 인식하고 값이 실제로 반환되어야하는 경우에만 행을 봅니다.

MySQL 그러나 모든 행을 조회합니다.

이 같은 쿼리를 다시 작성하십시오 :

SELECT news.* 
FROM (
     SELECT id 
     FROM news 
     WHERE cat_id='4' 
     ORDER BY 
       id DESC 
     LIMIT 150000, 10 
     ) o 
JOIN news 
ON  news.id = o.id 
+0

쿼리가 훨씬 더 빠르게 작동하는 것 같지만 이유를 이해할 수 없습니다. 이유를 말씀해 주시겠습니까? – intacto

+1

늦은 행 조회, 내 게시물 에이 설명했다. 내 쿼리는 테이블 자체에서 '10'레코드 만 선택하고, 원래 쿼리는 모든 '150,000'레코드를 선택하여 버립니다. 오늘 저녁에 블로그 게시물을 작성하겠습니다. 자세한 내용은이 블로그에서 자세히 다루겠습니다. – Quassnoi

+0

이드를 가져 가면 더 빨리, 감사하게 생각합니다. – intacto