2012-05-21 2 views
0

Doctrine2를 사용하는 Symfony2 프로젝트에서 쿼리가 느리다. 나는 이것이 무엇을 늦추는 지 확신 할 수 없다. 나는 그것을 추적하려고 노력했지만 아이디어가 부족하다. 기본 아이디어는 주어진 피드 (ID로)에서 처음 20 개의 기사를 가져 와서 게시 날짜별로 정렬하려는 것입니다. 내 개발 기계 (생산 기계에 수천 가지가있다)에 약 300 개의 기사를 분류 할 때 1 초는 길다.느린 쿼리 최적화하기 MySQL InnoDB (Doctrine2)

쿼리는 다음과 같습니다

SELECT 
    a0_.id AS id0, a0_.guid AS guid1, a0_.title AS title2, a0_.pub_date AS pub_date3, 
    a0_.summary AS summary4, a0_.content AS content5, a0_.source_url AS source_url6, 
    a0_.comment_url AS comment_url7, a0_.slug AS slug8, a0_.bitly_url AS bitly_url9, 
    a0_.thumbnail_id AS thumbnail_id10, a0_.feed_id AS feed_id11, 
    a0_.author_id AS author_id12 
FROM 
    articles a0_ 
WHERE 
    a0_.feed_id = ? 
ORDER BY 
    a0_.pub_date DESC LIMIT 20 

Parameters: ['19'] 
Time: 958.46 ms 

는 EXPLAIN 실행, 난이 얻을 :

+--------------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+--------------+------------------+------+-----+---------+----------------+ 
| id   | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| guid   | varchar(255)  | NO |  | NULL |    | 
| title  | varchar(255)  | NO |  | NULL |    | 
| author_id | int(10) unsigned | YES | MUL | NULL |    | 
| pub_date  | datetime   | YES | MUL | NULL |    | 
| summary  | text    | YES |  | NULL |    | 
| content  | text    | NO |  | NULL |    | 
| source_url | varchar(255)  | YES |  | NULL |    | 
| comment_url | varchar(255)  | YES |  | NULL |    | 
| feed_id  | int(10) unsigned | NO | MUL | NULL |    | 
| slug   | varchar(64)  | NO | MUL | NULL |    | 
| bitly_url | varchar(32)  | YES |  | NULL |    | 
| thumbnail_id | int(10) unsigned | YES | UNI | NULL |    | 
+--------------+------------------+------+-----+---------+----------------+ 
13 rows in set (0.09 sec) 

그리고 내 지표 :

+----------+------------+-----------------------+--------------+--------------+----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+-----------------------+--------------+--------------+------------------------+----------+--------+------+------------+---------+---------------+ 
| articles |   0 | PRIMARY    |   1 | id   | A   |  51479 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   0 | feed_guid    |   1 | feed_id  | A   |   352 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   0 | feed_guid    |   2 | guid   | A   |   352 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   0 | article_slug_unique |   1 | feed_id  | A   |   352 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   0 | article_slug_unique |   2 | slug   | A   |   352 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   0 | UNIQ_BFDD3168FDFF2E92 |   1 | thumbnail_id | A   |  51479 |  NULL | NULL | YES | BTREE  |   |    | 
| articles |   1 | author    |   1 | author_id | A   |  3677 |  NULL | NULL | YES | BTREE  |   |    | 
| articles |   1 | feed     |   1 | feed_id  | A   |  1660 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   1 | slug_idx    |   1 | slug   | A   |  51479 |  NULL | NULL |  | BTREE  |   |    | 
| articles |   1 | pub_date_idx   |   1 | pub_date  | A   |  51479 |  NULL | NULL | YES | BTREE  |   |    | 
+----------+------------+-----------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
10 rows in set (0.68 sec) 
이 내 테이블

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: a0_ 
     type: ref 
possible_keys: feed_guid,article_slug_unique,feed 
      key: feed_guid 
     key_len: 4 
      ref: const 
     rows: 338 
     Extra: Using where; Using filesort 
1 row in set (0.11 sec) 

을 01 23,516,

그리고 도움이된다면, 여기에 Doctrine2 코드입니다 : 내가 MySQL이 레코드를 주문 내 pub_date_idx 인덱스를 사용하여 얻을 수있는 몇 가지 방법이 있어야합니다 생각하고

$dql = $this->getEntityManager() 
     ->createQueryBuilder() 
     ->select('art') 
     ->from('MyMainBundle:Article', 'art') 
     ->where('art.feed = :f_id') 
     ->orderBy('art.pubDate', 'DESC'); 

은. ORDER BY에 사용 된 열에 인덱스를 사용해야한다고 생각했기 때문에 특별히 인덱스를 추가했습니다. 이 쿼리 성능을 개선하는 데 도움을주십시오.

+0

강제로 'FORCE' 인덱스 힌트 절을 지정하여 특정 인덱스를 강제 실행할 수 있습니다. 예 : 'FROM articles a0_ FORCE INDEX FOR ORDER BY (pub_date_idx)'. 자세한 내용은 [매뉴얼] (http://dev.mysql.com/doc/en/join.html)을 참조하십시오. – eggyal

+0

색인 힌트를 피하려고합니다. 최적화 도구가 작업을 수행 할 수 있도록 내 인덱스/쿼리를 설정할 수 있기를 바랍니다. 또한, Doctrine2로 작업하게하는 것은 까다로운 일입니다. – Matt

+0

나는 Doctrine을 사용하고 최근 비슷한 질문을했다. (http://stackoverflow.com/questions/12768235/optimising-mysql-queries-with-heavy-joins). 인덱스는 InnoDB에서 처음 나타나는 것처럼 빠르지는 않습니다. 클러스터링을 사용하면 더 잘 수행 할 수 있습니다. – Ryall

답변

1

인덱스를 사용하려면이 쿼리에 (피드, pubDate) 인덱스가 있어야합니다.

CREATE INDEX idx_feed_pub_date ON articles (feed_id, pub_date) 
+0

물론 많은 의미가 있습니다. – Matt