在查询中设置索引的正确方法

时间:2013-07-28 08:12:55

标签: mysql

我有2张桌子。

首先 - 表t_games(别名g)

column    type    
g_id      mediumint(8)    
t_id_1    smallint(5)    
t_id_2    smallint(5)    
g_team_1  varchar(50) 
g_team_2  varchar(50)
g_date    datetime    
g_live    tinyint(3)

在g_id字段上设置主索引,并在(t_id_1,t_id_2,g_date,g_live)字段上设置其他复合索引。

第二个 - 表t_teams(别名:t1和t2)

column    type    
t_id      smallint(5)    
t_gw_name varchar(50)
gw_cid    tinyint(3) 

主要索引在t_id上设置。

表之间的关系 已更新

每场比赛有两支球队。在表t_teams中有团队名称。在t_games表中,我保持ID与t_teams相关,以检索参与游戏的每个团队的名称。所以用团队名称来检索游戏ID:

SELECT g.g_id, t1.t_gw_name, t2.t_gw_name FROM t_games g
JOIN t_teams t1 ON (g.t_id_1 = t1.t_id)
JOIN t_teams t2 ON (g.t_id_2 = t2.t_id)

我的SQL查询:

SELECT g_id, t_id_1, t_id_2, g_team_1, g_team_2, g_date, g_live, t1.t_gw_name AS t_gw_name_1, t1.gw_cid AS gw_cid_1, t2.t_gw_name AS t_gw_name_2, t2.gw_cid AS gw_cid_2
FROM t_games g
JOIN t_teams t1 ON (t_id_1 = t1.t_id) JOIN t_teams t2 ON (t_id_2 = t2.t_id)
WHERE g.g_date < "2013-07-24 20:00:00" AND g.g_live < 2`

经过解释,我得到: `

1     SIMPLE            g       ALL         t_id_1        NULL    NULL    NULL       16     Using where
1     SIMPLE            t1     eq_ref       PRIMARY     PRIMARY     2     t_id_1     1     
1     SIMPLE            t2     eq_ref       PRIMARY     PRIMARY     2     t_id_2     1`

我尝试了很多索引表的组合,但我无法摆脱ALL扫描。

1 个答案:

答案 0 :(得分:1)

在您的情况下(对于您显示的查询),您只需要一个涵盖单个g_date的索引。

您看到ALL因为:

  1. 表格中只有16行(?)
  2. 您选择了超过表格行数的30%
  3. 在这两种情况下,扫描所有表格比使用索引更容易。

    所以检查g_date索引是否有效:

    1. t_games表格中添加1000行
    2. 执行将从t_games table
    3. 返回约10行的查询

      PS:

      1. 复合索引(g_date, g_live)将无效,因为您对两列都进行了范围比较
      2. g_live不会工作非常有效,因为它是该列的低基数