2012-04-08 3 views
2

Предположим, у меня есть эта таблица:MySQL Index + Query

create table table_a (
    id int, 
    name varchar(25), 
    address varchar(25), 
    primary key (id) 
) engine = innodb; 

Когда я бегу этот вопрос:

select * from table_a where id >= 'x' and name = 'test'; 

Как будет обрабатывать MySQL это? Будет ли он вытащить все идентификаторы первого (предположим 1000 строк), а затем применить предложение where = test?

Или, пока он ищет идентификаторы, он уже применяет предложение where в то же время?

ответ

2

В качестве идентификатора PK (и без индекса по имени) он будет загружать все строки, удовлетворяющие критерию, основанному на id, в память, после чего он будет фильтровать результирующий набор по критерию имени. Добавление составного индекса, содержащего оба поля, означает, что он будет загружать только записи, которые удовлетворяют обоим критериям. Добавление отдельного индекса одного столбца в поле имени может не привести к операции слияния индекса, и в этом случае индекс не будет иметь никакого эффекта.

+0

Я не уверен, что отдельные индексы для id и name окажут такое же влияние на производительность с наличием составного индекса. Вы уверены, что? –

+0

@AtaS. - Это будет зависеть от оптимизатора. Он может предпочесть сделать слияние индексов, и в этом случае он будет иметь аналогичное преимущество при использовании составного индекса, но это может и не быть. - [Оптимизация слияния индексов] (http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html) – nnichols

+0

Предположим, что таблица имеет несколько столбцов текста, и я все еще запускаю один и тот же запрос, то, как вы сказали, он сначала возьмет все строки, а затем применит предложение фильтра. В этом случае текстовые столбцы очень дороги для размещения внутри памяти. Это верно? – Carmen

0

У вас есть индексы в любой колонке? Это может повлиять на план выполнения. Другое дело, что можно было бы указать «x» :: int, чтобы обеспечить числовое сравнение вместо сравнения строк.

0

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

В вашем случае я не могу ответить на влияние первичного индекса на этот запрос. Это зависит от СУБД и версий. Если вы действительно не хотите ставить больше индекса (потому что больше индекса означает медленную запись и обновления), просто заселите свою таблицу с 10.000.000 случайными результатами, попробуйте и посмотрите эффект.

0

Вы можете получить информацию о том, как обрабатывается запрос, выполнив EXPLAIN по запросу.

Если идея состоит в том, чтобы оптимизировать этот запрос, то вы можете добавить индекс, как:

alter table table_a add unique index name_id_idx (name, id); 

0

вы можете сравнить время выполнения, выполнив запрос первого, когда идентификатор приходит первым в предложении where, а затем обмениваться и приносить имя в первую очередь. чтобы увидеть пример производительности mysql с индексами, проверьте это http://www.mysqlperformanceblog.com/2006/06/02/indexes-in-mysql/