Mysql - 查询和索引

时间:2013-07-01 07:40:58

标签: php mysql codeigniter

我想了解有关使用索引的内容和方法以及更好的SQL查询的想法和想法。

以下是我的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               

我是那个使用大量LEFT JOIN并在主键上连接它们的人......我的朋友告诉我使用索引来提高速度以获得结果..当我发现索引减慢时我感到困惑编写查询的速度:INSERT,DELETE,UPDATE,其中album和albuminfos表可能随时有新的/更新的记录..所以我很迷茫,所以我想倾听并从专业人士那里得到想法:

  1. 我的查询好吗?
  2. 我在mysql EXPLAIN中需要知道什么?
    • 索引是否可以使用?如果是..怎么样?
  3. 我的设置中是非?
  4. 谢谢!

2 个答案:

答案 0 :(得分:1)

问题1:

将子句与子句分开(它更易于阅读且更符合逻辑),否则您的查询似乎是旧的。

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 :(得分:0)

您能否使用“SHOW CREATE TABLE”提供有关表格的更多详细信息?

从EXLPAIN输出看来,您当前的键(它们是PRIMARY键)对于此SQL来说已经足够了。如您所见,EXPLAIN中的所有行都表示正在使用KEY(PRIMARY)。

我建议阅读http://dev.mysql.com/doc/refman/5.0/en/explain-output.html如何解释输出,最重要的是要注意的是, possible_key NULL (意味着你不是使用任何键进行数据选择),是一个小数字(除非你没有匹配任何东西,那么表格中的总行数就可以了),额外不应该说使用临时;使用filesort ,这意味着正在进行较慢的连接/排序/选择/搜索。