2013-07-01 97 views
1

我想获得关于什么/如何使用索引和更好的SQL查询的想法和想法。Mysql - 查询和索引

这里是我的SQL查询的示例:

SELECT albums.id AS album_id, albums.name AS album_name, albums.upc, albums.status, 
albumstatus.description AS album_status, DATE_FORMAT(albums.created, '%Y-%m-%d') AS created_date, 
albuminfos.label 
FROM albums,albumstatus, albumtypes, albuminfos 
WHERE albums.status = albumstatus.id AND albumtypes.id = albums.albumtype_id AND albums.id = albuminfos.id 
AND albums.account_id = 9999 
AND albums.status IN (1, 2) 

,我试图使用MySQL的EXPLAIN输出:

id select_type table  type possible_keys       key   key_len ref            rows Extra   

1 SIMPLE  albums  ref  PRIMARY,account_id,status,albumtype_id account_id 4  const           4148 Using where 
1 SIMPLE  albumstatus eq_ref PRIMARY,id        PRIMARY  4  albums.status    1 Using where 
1 SIMPLE  albumtypes eq_ref PRIMARY         PRIMARY  1  albums.albumtype_id  1 Using index 
1 SIMPLE  albuminfos eq_ref PRIMARY         PRIMARY  4  albums.id     1    

进出口,使用了大量的家伙左加入和连接他们在主键...我的朋友告诉我使用索引来提高速度得到结果..我感到困惑时,我f这些指标减慢了写查询的速度:INSERT,DELETE,UPDATE其中album和albuminfos表可能随时有新的/更新的记录..所以我很迷茫,所以我想倾听并从中获得想法专业:

  1. 是我查询的好吗?
  2. 我在mysql EXPLAIN中需要知道些什么?
    • 索引是否可以使用?如果是的话。怎么样?
  3. 正确与错误在我的设置?

谢谢!

+0

所有的表都在使用索引。 PRIMARY表示也是索引的主键。 – DevZer0

+0

你正在使用很多* LEFT JOINs?他们在哪? –

+0

@ypercube我一直以为'从专辑,albumstatus,albumtypes,albuminfos WHERE albums.status = albumstatus.id AND albumtypes.id = albums.albumtype_id AND albums.id = albuminfos.id ' 总是在左连接,正确吗? –

回答

1

问题1:从where子句中(这是更易于阅读和更合乎逻辑的),否则您的查询似乎是正确的旧的方式

单独加入。

SELECT albums.id AS album_id, albums.name AS album_name, albums.upc, albums.status, 
    albumstatus.description AS album_status, DATE_FORMAT(albums.created, '%Y-%m-%d') AS created_date, 
    albuminfos.label 
FROM albums 
LEFT OUTER JOIN albumstatus sta ON albums.status = albumstatus.id 
LEFT OUTER JOIN albumtypes typ ON albumtypes.id = albums.albumtype_id 
LEFT OUTER JOIN albuminfos inf ON albums.id  = albuminfos.id 
WHERE albums.account_id = 9999 AND albums.status IN (1, 2) ; 

您的索引是正确的。

对于化合物指数(@ypercube):

ALTER TABLE albums ADD INDEX idx_account_id (account_id ASC, status ASC) ; 

问题2:

Force MySQL to use two indexes on a Join

然而MySQL做它通常是良好。

问题3:

您的表格相册中有多少条记录?

+1

再次读取查询,可以在'(account_id,status)'或'((状态,account_id)'会比2个单独的索引更有效率(无论如何只有'account_id'索引被使用)。 –

+0

@kmas相册表如果没有被过滤是65k +记录 –

+0

它不是一个大的,所以你不应该有它的性能问题。复合索引可以像ypercube告诉你的那样改进查询,但不一定。 – kmas

0

你可以通过使用“SHOW CREATE TABLE”来提供关于表格的更多细节吗?

从EXLPAIN输出看来,您的当前键(这是主键)足以用于此SQL。正如你所看到的,EXPLAIN中的所有行都声明了一个KEY正在被使用(PRIMARY之一)。

我建议阅读http://dev.mysql.com/doc/refman/5.0/en/explain-output.html如何解释输出,最重要的事情看出来的是,possible_keyNULL(意思是不使用的数据选择任意键),感一个小数字(除非你不匹配任何东西,那么表中的总行数就OK),额外不应该说像的东西使用临时;使用filesort这意味着正在执行较慢的加入/排序/选择/搜索。

+0

谢谢你分享这个想法。所以如果可能的话,一个好的设置总是为每个表放置一个主键。如果不是什么情况可以呢? –

+0

http://stackoverflow.com/questions/2878272/when-i-should-use-primary-key-or-index – kmas