Задавайте вопросы, мы ответим
Вы не зашли.
Собственно, хочу разобраться, как используются индексы при JOIN (когда присутствуют дополнительные условия на таблицы).
Есть 2 таблицы
CREATE TABLE t1 (id int NOT NULL PRIMAYRY);
CREATE TABLE t2 (id int, param int);
И для них есть запрос с объединением
SELECT t1.id, t2.param
FROM t1 JOIN t2 USING (id)
WHERE t2.param>99999
Какой набор индексов будет оптимальным?
Понятно, что в первой таблице есть PRIMARY по id, и он не будет лишним. Вопрос по второй таблице...
1. Я так понимаю индекс по полю t2.id понадобится непосредственно для объединения. Верно?
2. Далее, для условия "param>99999" нам было бы неплохо тоже использовать индекс. Так вот наконец собственно вопрос, нам лучше иметь индекс (t2.id, t2.param) или лучше просто (t2.id), (t2.param).
Пытаюсь понять, какой индекс MYSQL использует после объединения - новый (t2.param), или продолжает использовать хвост того индекса, по которому мы и проводили объединение (t2.id, t2.param).
PS: Если это где-то уже описано в доках на русском - то просто киньте в меня ссылкой.
Спасибо.
Неактивен
Shad написал:
для условия "param>99999" нам было бы неплохо тоже использовать индекс. Так вот наконец собственно вопрос, нам лучше иметь индекс (t2.id, t2.param) или лучше просто (t2.id), (t2.param).
Используйте отдельные индексы для двух столбцов: если сделаете индекс (id, param), то по частям от него можно будет использовать только левую (другими словами, запрос по столбцу id в таком случае будет использовать индекс, а по столбцу param - нет).
Shad написал:
Пытаюсь понять, какой индекс MYSQL использует после объединения - новый (t2.param), или продолжает использовать хвост того индекса, по которому мы и проводили объединение (t2.id, t2.param).
Вам поможет конструкция EXPLAIN
(просто пишете EXPLAIN ваш_запрос
совет: запрос лучше завершайте не точкой с запятой, а последовательностью \G - будет поудобнее читать)
http://dev.mysql.com/doc/refman/5.0/en/explain.html
Поглядите на значения параметров possible_keys и key.
Если будут не те, что Вам хочется - воспользуйтесь USE INDEX или FORCE INDEX
http://dev.mysql.com/doc/refman/5.1/en/index-hints.html
P.S. На русском, к сожалению, не в курсе, где найти.
Неактивен
Спасибо за ответ.
А можно еще вопрос?
Где в EXPLAIN указывается идекс, по которому идет объединение таблиц. В поле key, я так понимаю, указывается индекс, который используется в условиях выборки. Нет?
Вообще, при объединении таблиц может быть использовано 3 ключа? (1 на группировку и по 1, скажем, на условия where по каждой из таблиц)?
Неактивен
В обычных условиях MySQL использует 1 индекс на таблицу. Изредка возможно
использование алгоритма MERGE_INDEX, но в 99.9% случаев Вы его не будете
использовать.
Заодно свой комментарий по первому Вашему запросу. Если Вы сделаете двойной
индекс на второй таблице в другом порядке - на (param,id), то вторую таблицу
вообще можно будет не читать, т.к. все данные для группировки будут в индексе.
Это даст дополнительное ускорение при работе с MyISAM.
Неактивен
Спасибо, тоже полезная информация. Но полной ясности в какой очередности проверяются ключи и как с этим делом завязано объединение таблиц у меня так и не появилось.
Все-таки где-нибудь можно найти информацию (на любом языке) в стиле:
1. Сначала Mysql проходит первую таблицу, проверяя по ключу условия.
2. Затем проверяет условия во второй таблице, используя префикс составного индекса.
3. Потом берет суффикс составного индекса и primary из первой таблицы и производит объединение.
4. Затем проводит сортировку, используя суффикс/префикс составного индекса.
Это я просто к примеру. Естественно, все совсем не так. Но как именно? Как это все происходит на низком уровне?
Неактивен
Сначала Ваш запрос проходит в оптимизатор. Там он строит план (который показывает
EXPLAIN). Запрос выполняется обычно по тому плану, который построил оптимизатор.
При объединении таблиц сначала выбирается первая строка из первой таблицы, которая
удовлетворяет условиям. Для нее выбирается первая строка следующей таблицы. И так далее.
Потом выбирается следующая строка.
Индексы используются где удастся. Например, если у Вас есть индекс на второй таблице
по условию связки 1 к 1, из второй таблицы будет выбрана только 1 строка для каждой
строки первой таблицы.
Неактивен
Т.е. по сути, в вашем примере, для первой таблицы индекс нужен только для проверки условия?
В объединении будет участвовать только индекс второй таблицы (по полю связки)?
Неактивен
Да.
Неактивен