遅いクエリMySQL InnoDBの最適化(Doctrine2)
-
12-12-2019 - |
質問
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
.このクエリのパフォーマンスを向上させるのを手伝ってください。
解決
このクエリでindexを使用するには、(feed、pubDate)のインデックスが必要です。あなたがそれを置く場合、それはうまくいくはずです:
CREATE INDEX idx_feed_pub_date ON articles (feed_id, pub_date)
所属していません StackOverflow