私は MySQL バージョン 5.0.95 で Drupal 6 を使用しており、最新の記事の日付に基づいてコンテンツを表示するクエリの 1 つが遅くなり、使用頻度が高いためにサイトのパフォーマンスが完全に低下するという行き詰まりに陥っています。問題のクエリは次のとおりです。
SELECT n.nid,
n.title,
ma.field_article_date_format_value,
ma.field_article_summary_value
FROM node n
INNER JOIN content_type_article ma ON n.nid=ma.nid
INNER JOIN term_node tn ON n.nid=tn.nid
WHERE tn.tid= 153
AND n.status=1
ORDER BY ma.field_article_date_format_value DESC
LIMIT 0, 11;
クエリの EXPLAIN は、以下の結果を示しています。
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
| 1 | SIMPLE | tn | ref | PRIMARY,nid | PRIMARY | 4 | const | 19006 | Using temporary; Using filesort |
| 1 | SIMPLE | ma | ref | nid,ix_article_date | nid | 4 | drupal_mm_stg.tn.nid | 1 | |
| 1 | SIMPLE | n | eq_ref | PRIMARY,node_status_type | PRIMARY | 4 | drupal_mm_stg.ma.nid | 1 | Using where |
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
このクエリは比較的単純でわかりやすいように見え、カテゴリ (用語) 153 に属し、ステータス 1 (公開済み) の記事を取得します。しかし、一時テーブルの使用とファイルソートの使用は、私がそれについて閲覧したことから、クエリが失敗することを意味しているようです。
ORDER BY 句から field_article_date_format_value を削除すると、Using temporary; が解決されます。ファイルソートを使用すると、クエリの実行時間が短縮されますが、必要であり、トレードオフすることはできません。残念ながら、サイトのパフォーマンスについても同様に当てはまります。
私の推測では、問題のほとんどは、記事をカテゴリにマップする term_node テーブルに起因するものであり、記事 X が 5 つのカテゴリ C1....C5 に関連付けられている場合、そのテーブルには 5 つのエントリがあることを意味する多対多の関係テーブルです。このテーブルは、すぐに使える drupal のものです。
重いDBコンテンツを扱うことは私にとって新しいことであり、同様のクエリのいくつかを経験しています( 日付デスクで注文する場合、「一時的なものを使用する」とクエリが 遅くなります.MySQLパフォーマンスの最適化:datetimeフィールドによる注文) datetime フィールドが ORDER BY 句で別のキー (nid) と共に使用され、FORCE INDEX を試みた content_type_article。
SELECT n.nid, n.title,
ma.field_article_date_format_value,
ma.field_article_summary_value
FROM node n
INNER JOIN content_type_article ma FORCE INDEX (ix_article_date) ON n.nid=ma.nid
INNER JOIN term_node tn ON n.nid=tn.nid
WHERE tn.tid= 153
AND n.status=1
ORDER BY ma.field_article_date_format_value DESC
LIMIT 0, 11;
結果と次の EXPLAIN クエリはあまり役に立たなかったようです
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+
| 1 | SIMPLE | tn | ref | PRIMARY,nid | PRIMARY | 4 | const | 18748 | Using temporary; Using filesort |
| 1 | SIMPLE | ma | ref | ix_article_date | ix_article_date | 4 | drupal_mm_stg.tn.nid | 1 | |
| 1 | SIMPLE | n | eq_ref | PRIMARY,node_status_type | PRIMARY | 4 | drupal_mm_stg.ma.nid | 1 | Using where |
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+
フィールド n.nid、ca.nid、ma.field_article_date_format_value はすべて索引付けされています。Limit 0,11 で DB をクエリすると、ORDER BY 句を使用すると約 7 ~ 10 秒かかりますが、ORDER BY 句を使用しない場合、クエリはほとんど 1 秒かかりません。データベース エンジンは MyISAM です。これに関するヘルプは大歓迎です。
このクエリを通常のクエリのように(日付でソートしないクエリと同じ速度で)取得するのに役立つ回答はどれも素晴らしいでしょう。nid
とを組み合わせてクエリで使用する複合クエリを作成しようとした私の試みはfield_article_date_format_value
、原因を解決しませんでした。問題に関する追加情報と新しい提案を提供することにオープンです。