索引可用时的全表扫描

时间:2010-11-17 19:01:27

标签: sql mysql database performance

我有一些类似的联接集合的查询。由于某些原因,他们都遭受了其中一个连接的表扫描。

   SELECT S.shape_id, 
          S.title, 
          G.grid_id, 
          CI.city_id, 
          CI.city_name, 
          CO.country_code, 
          CO.country, 
          U.user_id, 
          U.username, 
          GA.first_name, 
          GA.fb_id 
     FROM shape S 
     JOIN spots SP ON S.shape_id = SP.shape_id 
     JOIN grid G ON SP.grid_id = G.grid_id 
     JOIN city CI on G.city_id = CI.city_id 
     JOIN country CO ON CI.country_code = CO.country_code 
     JOIN user U on S.user_id = U.user_id 
LEFT JOIN gamer GA ON U.user_id = GA.user_id 
    WHERE S.status > 0
      AND U.user_id != 2579 
 ORDER BY S.views ASC 
    LIMIT 111, 1

表扫描似乎总是在'grid'/'G'表上。

这是'EXPLAIN'

    ID - SELECT TYPE - TABLE - TYPE - POSS KEYS - KEY - KEY LEN - REF - ROWS - EXTRA
    -----------------------------------------------------------------------------------
    1 - SIMPLE - G - ALL - PRIMARY - null - null - null - 405 - Using temporary; Using filesort    
    1 - SIMPLE - CI - eq_ref - PRIMARY - PRIMARY - 3 - ft_game.G.city_id - 1     
    1 - SIMPLE - CO - eq_ref - PRIMARY - PRIMARY - 6 - ft_game.CI.country_code - 1     
    1 - SIMPLE - SP - ref - shape_id,grid_id - grid_id - 4 - ft_game.G.grid_id - 1 - Using where    
    1 - SIMPLE - S - eq_ref - PRIMARY,user_id - PRIMARY - 4 - ft_game.SP.shape_id - 1 - Using where    
    1 - SIMPLE - U - eq_ref - PRIMARY - PRIMARY - 3 - ft_game.S.user_id - 1     
    1 - SIMPLE - GA - eq_ref - PRIMARY - PRIMARY - 3 - ft_game.S.user_id - 1
  1. 我对解释的顺序感到困惑......为什么G(网格)先行?
  2. 当我有一个G.grid_id(主键)键时,为什么网格上有表扫描。
  3. 为什么要创建临时表?

2 个答案:

答案 0 :(得分:0)

我不是mysql的大师。另一方面,我认为Oracle的基线是相似的。基于它们:

全表扫描或索引扫描背后的主要驱动因素是选择性。列中存在的值越多,使用索引的可能性就越大。如果数据库预计将获取超过10%的行,则可能会使用全表扫描。

我认为gridId在网格表中是唯一的。所以选择性很高。但是你使用其他列city_id。这意味着,即使您使用索引来获取id,也需要表数据,因为附加列就在那里。如果这意味着,将提取超过10%的行,则不会使用索引。

有多种连接方法。基于join method,存在不同的行为。

对于hash joinnested loops,驱动程序表是较小或最小的,或具有最具选择性谓词的驱动程序表。所以我认为网格是你最小的桌子。由于你的SQL没有任何基于等价的条件(你有一个>和一个!=),你不应该怀疑该数据库是否会使用最小的表作为驱动程序。

因此,全表扫描的主要原因是您没有任何选择条件,数据库应从全表扫描开始,并选择网格。多数民众赞成。

答案 1 :(得分:0)

你说这张桌子只有400行。我知道在SQL Server中,不太可能在这样的小表中使用索引。我怀疑mySQL会有同样的感觉。

如果表很大并且仍未使用索引,请检查以确保您具有良好的索引以供其使用。例如,FK通常应该被索引,有些人认为它们是自动的,但它们并不在所有数据库中。你会惊讶地发现你的第一张支票经常没有显示你确定会有的指数。

相关问题