私は2つのテーブルを持っています:
CREATE TABLE `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(1000) DEFAULT NULL,
`last_updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `last_updated` (`last_updated`),
) ENGINE=InnoDB AUTO_INCREMENT=799681 DEFAULT CHARSET=utf8
CREATE TABLE `article_categories` (
`article_id` int(11) NOT NULL DEFAULT '0',
`category_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`article_id`,`category_id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
これは私のクエリです:
SELECT a.*
FROM
articles AS a,
article_categories AS c
WHERE
a.id = c.article_id
AND c.category_id = 78
AND a.comment_cnt > 0
AND a.deleted = 0
ORDER BY a.last_updated
LIMIT 100, 20
そしてそれのEXPLAIN
ため:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: a
type: index
possible_keys: PRIMARY
key: last_updated
key_len: 9
ref: NULL
rows: 2040
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: eq_ref
possible_keys: PRIMARY,fandom_id
key: PRIMARY
key_len: 8
ref: db.a.id,const
rows: 1
Extra: Using index
ソートには最初のテーブルのフル インデックス スキャンをlast_updated
使用しますが、結合には y インデックスを使用しません (type: index
説明内)。これは非常に頻繁なクエリであるため、パフォーマンスが非常に悪く、データベース サーバー全体が停止します。
を使用してテーブルの順序を逆にしてみましSTRAIGHT_JOIN
たが、これにより が得られfilesort, using_temporary
、これはさらに悪いことです。
結合とソートに同時に mysql にインデックスを使用させる方法はありますか?
===更新===
私はこれで本当に絶望的です。たぶん、ある種の非正規化がここで役立つでしょうか?