我将 Drupal 6 与 MySQL 版本 5.0.95 一起使用,并且陷入僵局,其中一个基于最近文章日期显示内容的查询速度变慢,并且由于使用频率完全降低了站点性能。有问题的查询如下:
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;
查询的解释显示以下结果:
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
| 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 解决了使用临时性问题;使用 filesort 减少了查询执行时间,但它是必需的,不能折衷,不幸的是,同样适用于站点性能。
我的直觉是,大部分问题来自 term_node 表,该表将文章映射到类别,并且是多对多关系表,这意味着如果文章 X 与 5 个类别 C1..C5 相关联,它将在该表中有 5 个条目,此表来自开箱即用的 drupal。
处理繁重的数据库内容对我来说是新事物,并且经历了一些类似的查询( 按日期 desc 排序时,“使用临时”会减慢查询速度, MySQL 性能优化:按日期时间字段排序)我尝试为在 ORDER BY 子句中使用其日期时间字段的 content_type_article 以及其中的另一个键 (nid) 并尝试强制索引。
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 均已编入索引。使用 ORDER BY 子句查询限制为 0,11 的数据库大约需要 7-10 秒,但没有它,查询几乎不需要一秒钟。数据库引擎是 MyISAM。对此的任何帮助将不胜感激。
任何可以帮助我像普通查询一样获得此查询的答案(与没有按日期排序的查询的速度相同)都会很棒。我尝试将复合查询创建为查询中的nid
andfield_article_date_format_value
和 use 的组合并没有帮助解决问题。我愿意提供有关该问题的更多信息和任何新建议。