полное сканирование таблицы при наличии индексов - PullRequest
1 голос
/ 17 ноября 2010

У меня есть несколько запросов с похожей коллекцией объединений. По какой-то причине все они страдают от сканирования таблицы на одном из соединений.

   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'.

Вот это "ОБЪЯСНИТЬ"

    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 голосов
/ 09 декабря 2010

Вы говорите, что в таблице только 400 строк.Я знаю, что в SQL Server вряд ли будет использоваться индекс в такой крошечной таблице.Я подозреваю, что MySQL будет чувствовать себя так же.

Если таблица большая и она по-прежнему не использует индекс, убедитесь, что у вас есть хороший индекс для ее использования.Например, FK обычно должны быть проиндексированы, и некоторые люди думают, что они автоматически, но они не во всех базах данных.Вы будете удивлены, как часто ваша первая проверка не показывает индекса для чего-то, в чем вы были уверены.

0 голосов
/ 18 ноября 2010

Я не MySQL гуру. С другой стороны, я думаю, что базовые показатели для Oracle схожи. По ним:

Основными драйверами полного сканирования таблицы или сканирования индекса является избирательность. Чем больше разных значений в столбце, тем более вероятным будет индекс. Если база данных ожидает, что будет выбрано более 10 процентов строк, она, скорее всего, будет использовать полное сканирование таблицы.

Полагаю, gridId уникален в таблице сетки. Так что селективность высокая. НО вы используете другой столбец city_id. Это означает, что даже если бы вы использовали индекс для извлечения идентификатора, данные таблицы также необходимы, поскольку там есть дополнительный столбец. И если это означает, что будет выбрано более 10 процентов строк, он не будет использовать индекс.

Существует несколько методов соединения. В зависимости от метода соединения присутствует другое поведение.

Для хеш-соединений и вложенных циклов таблица драйверов является меньшей или наименьшей или той, которая имеет самый избирательный предикат. Итак, я полагаю, что таблица является вашей самой маленькой таблицей. А так как ваш SQL не имеет условий, основанных на эквивалентности (у вас есть> и!!), Вы не должны удивляться, что эта база данных будет использовать наименьшую таблицу в качестве драйвера.

Таким образом, основная причина полного сканирования таблицы заключается в том, что у вас нет какого-либо выборочного условия, и база данных должна начинаться с полного сканирования таблицы, и она выбрала сетку. Вот и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...