我正在使用Drupal 6與MySQL版本5.0.95並處於僵局,其中顯示基於最近文章日期的內容的一個查詢速度變慢並且由於正在使用的頻率共同殺害現場表演。有問題的查詢如下:無法優化使用ORDER BY子句的MySQL查詢
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(已發佈)。但顯然使用臨時表和使用filesort意味着查詢必然會失敗,我所學到的瀏覽它。
從ORDER BY子句中刪除field_article_date_format_value可解決Using temporary;使用filesort可以減少查詢執行時間,但是這是必需的,不能交易,不幸的是,對於站點性能同樣如此。
我的預感是,大部分麻煩來自term_node表,它將文章映射到類別,並且是一個多關係表,這意味着如果文章X與5個類別C1關聯...... C5它將有5個條目在該表中,此表來自開箱即用的drupal。
重DB內容打交道是通過一些類似的查詢( When ordering by date desc, "Using temporary" slows down query, MySQL performance optimization: order by datetime field)我試圖創建的,其時間字段在ORDER沿着BY子句中使用content_type_article一個綜合指數的新的東西給我,去與另一個關鍵(NID),並試圖強制INDEX。
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查詢數據庫需要大約7-10秒的ORDER BY子句,但是如果沒有它,查詢幾乎不需要一秒鐘。數據庫引擎是MyISAM。任何幫助,將不勝感激。
任何答案都可以幫助我像普通的那樣獲得這個查詢(與查詢沒有按日期排序的速度相同),那將是很棒的。我嘗試創建組合查詢nid
和field_article_date_format_value
並在查詢中使用並沒有幫助原因。我願意提供有關該問題的更多信息和任何新建議。
感謝您的迴應,儘管term_node是N:N,對於特定的術語,所得到的節點在我的情況下將是截然不同的。我之前嘗試過派生表方法,但查詢執行與傳統方法幾乎相同。 – optimusprime619