2015-01-12 8 views
1

Я пытаюсь понять, можно ли использовать индекс в объединении, если нет ограничений, где на первой таблице.Используйте индекс в соединении без «где»

Примечание: это не линейное использование в реальном масштабе времени, а просто вещь, которую я собираю вместе для понимания целей. Не указывайте на очевидное «что вы пытаетесь получить с помощью этой схемы?», «Вы должны использовать UNSIGNED» или «понравится», потому что это не вопрос.

Примечание2: это MySQL JOINS without where clause так или иначе связаны, но не то же самое

Схема:

CREATE TABLE posts (
     id_post INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     text VARCHAR(100) 
     ); 

CREATE TABLE related (
     id_relation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     id_post1 INT NOT NULL, 
     id_post2 INT NOT NULL 
     ); 

CREATE INDEX related_join_index ON related(id_post1) using BTREE; 

Запрос:

EXPLAIN SELECT * FROM posts FORCE INDEX FOR JOIN(PRIMARY) INNER JOIN related ON id_post=id_post1 LIMIT 0,10; 

SQL Скрипки: http://sqlfiddle.com/#!2/84597/3

Как вы можете видеть, индекс используется во второй таблице, но th e движок делает полное сканирование таблицы на первом (FORCE INDEX - это просто для выделения общего вопроса).

Я хотел бы понять, можно ли также получить «ref» с левой стороны.

Спасибо!

Update: если первая таблица имеет значительно больший показатель, чем вторая, вещь замена: двигатель использует индекс для первого и полного сканирования таблицы для второго http://sqlfiddle.com/#!2/3a3bb/1 не менее, никакого способа получить индексы не используется на обоих.

+0

Возможно, это поможет: http://dev.mysql.com/doc/refman/5.5/ru/how-to-avoid-table-scan.html – EternalHour

+0

Также прочитайте этот ответ по аналогичному вопросу: http: /stackoverflow.com/questions/27897763/mysql-explain-showing-all-type-although-index-exists/27899245#27899245 – axiac

ответ

1

Существует page документации по этой теме.

Что касается возможности получить ref в первой таблице из запроса, то короткий ответ будет NO.

Причина очевидна: потому что нет WHERE пункта анализируется ВСЕ строки из таблицы posts, потому что они могут быть включены в наборе результатов. Нет причин использовать для этого индекс, полное сканирование таблицы лучше, потому что оно получает все строки; и поскольку порядок не имеет значения, доступ (более или менее) последователен. Использование индекса требует чтения дополнительной информации из хранилища (индекс и данные).

MySQL будет использовать тип соединения index, если все столбцы, отображаемые в пункте SELECT, представлены в индексе. В этом случае MySQL будет выполнять full index scan (тип соединения index) вместо full table scan (тип соединения ALL), поскольку он требует меньше информации из хранилища (индекс обычно меньше, чем все данные таблицы).

+0

Спасибо за ваш ответ, но как вы можете видеть здесь http://sqlfiddle.com/#! 2/3a3bb/1 На самом деле я получил eq_on на левой таблице. Тем не менее, ответ выглядит солидным для меня. Примите это скоро, если никто не даст другого. –

+0

Не использовать 'WHERE' не означает, что всегда будет сканирование таблицы. 'WHERE' не всегда требуется, если условия' JOIN' являются оптимальными. – EternalHour

+0

Просто примечание: вы написали «ВСЕ строки из табличных сообщений включены в набор результатов». Это ** INNER ** JOIN, поэтому строки на первой таблице не будут включены, если на втором не будет соответствующего. Я думаю, что использование индекса должно помочь здесь? –

3

В СУБД есть оптимизатор, который может найти лучший план для выполнения запроса. Оптимизатор должен решить, использовать ли индекс или просто прочитать таблицу напрямую.

Индекс имеет смысл, когда СУБД ожидает, что только несколько записей будут прочитаны из таблицы (скажем, всего 1% от всех строк). Но как только он ожидает, что прочитает много записей (скажем, 99% всех строк), он не будет использовать индекс. Порог может составлять минимум 5% (т.е. < = 5% -> индекс,> 5% сканирование таблицы).

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

+0

Неправильное предположение оптимизатора запросов имеет очень низкий шанс для таких простых запросов. Но хорошо, что вы это упомянули. – axiac

Смежные вопросы