[英]Optimizing Slow Query MySQL InnoDB (Doctrine2)
我在使用Doctrine2的Symfony2项目中查询很慢。 我不确定会导致这种情况减慢的原因。 我试图自己追踪它,但是用尽了所有想法。 基本思想是我想从给定的提要中获取前20篇文章(按ID),并按发布日期对它们进行排序。 当我在开发机器上(生产机器有数千个)对大约300篇文章进行排序时,似乎需要1秒的时间。
查询是:
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,我得到以下信息:
*************************** 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)
这是我的桌子:
+--------------+------------------+------+-----+---------+----------------+
| 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)
如果有帮助,这里是Doctrine2代码:
$dql = $this->getEntityManager()
->createQueryBuilder()
->select('art')
->from('MyMainBundle:Article', 'art')
->where('art.feed = :f_id')
->orderBy('art.pubDate', 'DESC');
我在想必须有某种方法让MySQL使用我的pub_date_idx
索引来排序记录。 我之所以特别添加了索引,是因为我认为我已经阅读过索引应该用于ORDER BY
的列。 请帮助我改善此查询性能。
您应该为此查询使用一个索引(Feed,pubDate)。 如果把它放出来应该可以解决:
CREATE INDEX idx_feed_pub_date ON articles (feed_id, pub_date)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.