2013-04-18 2 views
1

프로덕션 서버에서 정상적으로 작동하는 쿼리가 매우 느리게 시작되었습니다 (몇 시간 만에).간단한 SELECT mysql 쿼리가 매우 느림 (교차 사용)

이 그 것이다 :

SELECT * FROM news_articles WHERE published = '1' AND news_category_id = '4' ORDER BY date_edited DESC LIMIT 1;

이것은 EXPLAIN의 출력 (~ 테이블 갖는다 200.000 행) 실행 (20-30) 초까지 취

+----+-------------+---------------+-------------+----------------------------+----------------------------+---------+------+------+--------------------------------------------------------------------------+ 
| id | select_type | table   | type  | possible_keys    | key      | key_len | ref | rows | Extra                 | 
+----+-------------+---------------+-------------+----------------------------+----------------------------+---------+------+------+--------------------------------------------------------------------------+ 
| 1 | SIMPLE  | news_articles | index_merge | news_category_id,published | news_category_id,published | 5,5  | NULL | 8409 | Using intersect(news_category_id,published); Using where; Using filesort | 
+----+-------------+---------------+-------------+----------------------------+----------------------------+---------+------+------+--------------------------------------------------------------------------+ 

놀아 보니 특정 색인 ()는 훨씬 더 빨리 만드는 :

SELECT * FROM news_articles USE INDEX (date_edited) WHERE published = '1' AND news_category_id = '4' ORDER BY date_edited DESC LIMIT 1;

이 사람은을 실행하기 위해 밀리 초 걸립니다. 이 하나

EXPLAIN 출력은 다음과 같습니다

+----+-------------+---------------+-------+---------------+-------------+---------+------+------+-------------+ 
| id | select_type | table   | type | possible_keys | key   | key_len | ref | rows | Extra  | 
+----+-------------+---------------+-------+---------------+-------------+---------+------+------+-------------+ 
| 1 | SIMPLE  | news_articles | index | NULL   | date_edited | 8  | NULL | 1 | Using where | 
+----+-------------+---------------+-------+---------------+-------------+---------+------+------+-------------+ 

news_category_id, publisheddate_edited 모두 인덱싱됩니다.

스토리지 엔진은 InnoDB입니다.

CREATE TABLE `news_articles` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `title` text NOT NULL, 
    `subtitle` text NOT NULL, 
    `summary` text NOT NULL, 
    `keywords` varchar(500) DEFAULT NULL, 
    `body` mediumtext NOT NULL, 
    `source` varchar(255) DEFAULT NULL, 
    `source_visible` int(11) DEFAULT NULL, 
    `author_information` enum('none','name','signature') NOT NULL  DEFAULT 'name', 
    `date_added` datetime NOT NULL, 
    `date_edited` datetime NOT NULL, 
    `views` int(11) DEFAULT '0', 
    `news_category_id` int(11) DEFAULT NULL, 
    `user_id` int(11) DEFAULT NULL, 
    `c_forwarded` int(11) DEFAULT '0', 
    `published` int(11) DEFAULT '0', 
    `deleted` int(11) DEFAULT '0', 
    `permalink` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`), 
    KEY `news_category_id` (`news_category_id`), 
    KEY `published` (`published`), 
    KEY `deleted` (`deleted`), 
    KEY `date_edited` (`date_edited`), 
    CONSTRAINT `news_articles_ibfk_3` FOREIGN KEY (`news_category_id`) REFERENCES `news_categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, 
    CONSTRAINT `news_articles_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE 
) ENGINE=InnoDB AUTO_INCREMENT=192588 DEFAULT CHARSET=utf8 

나는 아마도 모두가 해당 인덱스를 사용하여 암시하는 않습니다 내 웹 응용 프로그램을 조회 변경할 수 있습니다 :

테이블 구조입니다. 그러나 이것은 상당한 연구입니다.

MySQL을 조정하여 실제로 모든 쿼리를 다시 작성하지 않고 첫 번째 쿼리를보다 효율적으로 만들 수 있습니까? = 1 AND date_edited DESC의 LIMIT 1 BY news_category_id = 4 ORDER를 발표 news_articles로부터

SELECT *;

+0

이 때 당신이 마지막으로 실행이'표 news_articles를 분석되었다'? 인덱스의 카디널리티를 업데이트해야 할 수도 있습니다. 또한 인덱스가 여러 필드에 걸쳐 있으면 성능이 향상 될 수 있습니다. – Wrikken

+0

또한 거의 언제나'date_edited' 명령을 사용하면'ALTER TABLE news_articles ORDER BY date_edited;'가 무엇인지 알 수 있습니다 (전체 테이블을 다시 생성한다는 점에 유의하십시오. 따라서 약간의 시간이 소요될 수 있습니다. (아마도 날짜) – Wrikken

+0

@Wrikken'ANALYZE'가 최근에 실행되었습니다. 여러 필드 인덱스 ('news_category_id','published','date_edited')를 사용 했었습니다. 나는 그것을 시험으로 떨어 뜨 렸지만 아무런 차이가 없었다. 나는 테이블이 이미 그 순서대로 정렬되어 있기 때문에 나를 위해 이해할 수있다. 행은 순서가 잘못되었을 수 있지만 대부분 edited_date에 의해 정렬됩니다) – vassilis

답변

관련 문제