2015-09-27 66 views
-1

,所以我在mysql中的两个表:文章和articles_rubrics,既〜20.000排SQL JOIN为了极大地改变了性能

文章有多个的cols,但它的article_id索引。

articles_rubrics只有两个列:article_id和rubrics_id,两者都被分别编入索引,最重要的是这两个链接的索引。

我的问题是,当我选择这些表中的数据与加盟,顺序是非常重要的,这对我来说是一个问题,我不明白它的原因:

SELECT article_id,rubric_id FROM articles 
LEFT JOIN articles_rubrics USING(article_id) 
WHERE rubric_id=1 
ORDER BY article_id DESC 
LIMIT 10; 

和解释说(为articles_rubrics)这样的:

time: 0.312 s 
key_len: 1 
ref: const 
rows: 7352 
extra: Using where; Using temporary; Using filesort 

但是当我切换它的顺序:

SELECT article_id,rubric_id FROM articles_rubrics 
LEFT JOIN articles USING(article_id) 
WHERE rubric_id=1 
ORDER BY article_id DESC 
LIMIT 10; 

,并解释说,(对于articles_rubrics)这样的:

time: 0.001 s 
key_len:9 
ref: NULL 
rows: 28 
extra: Using where; Using index 

所以我有两个表,这使得他们的查询去吧〜300倍慢/更快。这怎么可能呢?

PS:我已经很大程度上简化了我的现实世界中的问题在这个例子中,我偶然发现了这一点,因为我

SELECT * FROM articles [LEFT JOIN for 5 other tables] 

正在采取1.5秒,当我实际添加其他加入进来,执行时间改为0.006秒。

显示指数:

show index from articles; 
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment 
articles 0 PRIMARY 1 article_id A 20043 NULL NULL  BTREE   
articles 1 article_url_title 1 article_url_title A 10021 NULL NULL  BTREE   
articles 1 FULLTEXT 1 article_title NULL 1 NULL NULL  FULLTEXT   
articles 1 FULLTEXT 2 article_content NULL 1 NULL NULL  FULLTEXT   

show index from articles_rubrics; 
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type 
articles_rubrics 0 PRIMARY 1 article_id A NULL NULL NULL  BTREE 
articles_rubrics 0 PRIMARY 2 rubric_id A 20814 NULL NULL  BTREE 
articles_rubrics 1 rubric_id 1 rubric_id A 17 NULL NULL  BTREE 
articles_rubrics 1 article_id 1 article_id A 20814 NULL NULL  BTREE 
+1

你能提供这两个表上的指数吗? 'show index from table_name' –

+0

show index added – Gonzi

+1

请检查:这肯定看起来不正确....'FROM articles_rubrics LEFT JOIN articles_rubrics USING(article_id)'它加入自己。此外,请使用表格名称或别名中的所有引用列(包括where子句)的性能可能取决于您所引用的表格 –

回答

1
SELECT article_id,rubric_id 
FROM articles 
LEFT JOIN articles_rubrics USING(article_id) 
WHERE rubric_id=1 <<<<<<<<<<<<<<<<<<<<<<<<<<< problem here 
ORDER BY article_id DESC 
LIMIT 10; 

通过坚持每一行从该查询返回已rubric_id = 1你排除任何行,其中有2个表之间不匹配,因此没有点使用LEFT JOIN

SELECT a.article_id, ar.rubric_id 
FROM articles AS a 
INNER JOIN articles_rubrics AS ar ON a.article_id = ar.article_id 
WHERE ar.rubric_id = 1 
ORDER BY a.article_id DESC 
LIMIT 10; 

您需要在每个引用中使用表或表别名。

+0

'SELECT a.article_id,ar。rubric_id FROM制品的 INNER JOIN articles_rubrics AR ON a.article_id = ar.article_id WHERE ar.rubric_id = 1个 ORDER BY a.article_id DESC LIMIT 10;' 运行为0,2s,与LEFT JOIN运行像0.25s,但仍然应该运行0.001秒 – Gonzi

+0

该评论的目的是什么? –

+0

试过换行符,输入后,抱歉,修正。 – Gonzi

0

在数据库上加入操作是昂贵的过程。最好使用简单的SELECT嵌套。创建一个列表来存储数据,然后使用列表中的项目进行下一个查询。