[英]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.