简体   繁体   中英

Optimizing Slow Query MySQL InnoDB (Doctrine2)

I have a slow query in a Symfony2 project using Doctrine2. I am unsure about what is slowing this down. I have tried to track it down myself, but have run out of ideas. The basic idea is I want to get the first 20 articles from a given feed (by ID) and sort them by the date published. It seems like 1 second is kind of long when I am sorting on about 300 articles on my development machine (production machine has thousands).

The query is:

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

Running EXPLAIN, I get this:

*************************** 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)

This is my table:

+--------------+------------------+------+-----+---------+----------------+
| 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)

And my indices:

+----------+------------+-----------------------+--------------+--------------+----------+-------------+----------+--------+------+------------+---------+---------------+
| 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)

And if it helps, here is the Doctrine2 code:

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

I'm thinking there must be some way to get MySQL to use my pub_date_idx index to order the records. I had specifically added the index because I thought I had read that indices should be used for the columns used in ORDER BY . Please help me in improving this query performance.

you should have an index for (feed, pubDate) for this query to use index. it should work out if you put it:

CREATE INDEX idx_feed_pub_date ON articles (feed_id, pub_date)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM