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');
pub_date_idx
MySQL でインデックスを使用してレコードを並べ替える方法が必要だと考えています。で使用される列にインデックスを使用する必要があることを読んだと思ったので、特にインデックスを追加しましたORDER BY
。このクエリのパフォーマンスを改善するために私を助けてください。