sql join命令显着改变了性能

时间:2015-09-27 08:48:39

标签: mysql performance join database-performance

所以我在mysql中有两个表:articles和articles_rubrics,两者都有~20,000行

文章有多个cols,但其article_id已编入索引。

articles_rubrics只有两个cols: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

2 个答案:

答案 0 :(得分: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,您已经消除了两个表之间没有匹配的任何行,因此使用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;

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

答案 1 :(得分:0)

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