簡體   English   中英

如何在MySQL中優化這個令人困惑的慢查詢?

[英]How can I optimize this confusingly slow query in MySQL?

我有一個博客文章表,每個都有一個外鍵回到它的作者。 此表中有<15,000個條目。 此查詢掃描超過19,000行(每個EXPLAIN ),需要一個filesort(可能是常規的MySQL行為),並需要超過400毫秒才能返回5行。 可能是因為用於檢查項目是否實際發布的復雜WHERE

最親愛的Stack Overflow,我如何能夠控制這個查詢?

注意:雖然此標准可能需要簡化,但所有條件都是必需的。

SELECT      `blog_post.id`, 
            `blog_post.title`,
            `blog_post.author_id`,
            `blog_post.has_been_fact_checked`,
            `blog_post.published_date`,
            `blog_post.ordering`,
            `auth_user.username`,
            `auth_user.email`
FROM        `blog_post` 
INNER JOIN  `auth_user` 
ON          (`blog_post`.`author_id` = `auth_user`.`id`) 
WHERE       (`blog_post`.`is_approved` = True  AND 
             `blog_post`.`has_been_fact_checked` = True  AND 
             `blog_post`.`published_date` IS NOT NULL AND 
             `blog_post`.`published_date` <= '2010-10-25 22:40:05' ) 
ORDER BY    `blog_post`.`published_date` DESC, 
            `blog_post`.`ordering` ASC, 
            `blog_post`.`id` DESC 
LIMIT 5

除了PK,我在表上有以下索引:

idx_published_blog_post -> blog_post(is_approved, has_been_fact_checked, published_date)
idx_pub_date -> blog_post(published_date)

EXPLAIN的輸出如下所示:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: blog_post
         type: ref
possible_keys: blog_post_author_id,idx_published_blog_post,idx_pub_date
          key: idx_published_blog_post
      key_len: 4
          ref: const,const
         rows: 19856
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: auth_user
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: blog.blog_post.author_id
         rows: 1
        Extra: Using index
2 rows in set (0.00 sec)

附注: 2010-10-25 22:40:05只是執行此查詢的代碼生成的日期。

非常感謝任何和所有的幫助!

MySQL不支持索引中的ASC/DESC子句。

您需要創建一個名為reverse_ordering的單獨列,並將其值設置為-ordering (假設ordering是一個數值)

然后,您可以創建以下索引:

CREATE INDEX ix_blogpost_a_c_p_ro_id ON blog_post (is_approved, has_been_fact_checked, published_date, reverse_ordering, id)

並重寫您的查詢:

SELECT      `blog_post.id`, 
            `blog_post.title`,
            `blog_post.author_id`,
            `blog_post.has_been_fact_checked`,
            `blog_post.published_date`,
            `blog_post.ordering`,
            `auth_user.username`,
            `auth_user.email`
FROM        `blog_post` 
INNER JOIN  `auth_user` 
ON          `blog_post`.`author_id` = `auth_user`.`id`
WHERE       `blog_post`.`is_approved` = 1 AND 
            `blog_post`.`has_been_fact_checked` = 1 AND 
            `blog_post`.`published_date` <= '2010-10-25 22:40:05'
ORDER BY    `blog_post`.`published_date` DESC, 
            `blog_post`.`reverse_ordering` DESC, 
            `blog_post`.`id` DESC 
LIMIT 5

您可以擺脫IS NULL檢查,因為不等式條件意味着它。

更新:

您可能還想閱讀這篇文章:

使用您在query(where子句)中應用的所有條件來查看“blog_post”,並使用此視圖直接連接“auth_user”。

如果不清楚,請隨意問。 :)

對我來說,看起來文件可能會扼殺速度。 如果您可以將ORDER BY字段放入正在使用的索引中,則可能會提高速度。 嘗試改變:

idx_published_blog_post - > blog_post(is_approved,has_been_fact_checked,published_date)

idx_published_blog_post - > blog_post(is_approved,has_been_fact_checked,published_date DESC,訂購ASC,id DESC)

幾個想法:在什么情況下你有一個null published_date,在日期范圍內搜索可能會更快? Published_date似乎也是一個日期時間字段,所以在排序時你真的有這樣的帖子,你可以每秒發布一次你需要其他排序字段嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM