2015-06-15 1 views
3

У меня есть таблица movies. В нем 1,3 миллиона строк.Почему моя инструкция MySQL SELECT с ORDER BY настолько медленная, хотя INDEX находится в столбце?

Стол имеет INDEX на колонке title, заказ asc, длина 255.

Столбец title является VARCHAR(1000).

Даже при этой настройке следующий запрос занимает 8 секунд для запуска. Любые идеи или снимки в темноте, почему это может быть? Я в тупике, потому что кажется такой основной проблемой.

SELECT title 
FROM movies 
ORDER BY title 
LIMIT 150000, 50000 

Когда я вынуть ORDER BY, запрос супер быстрый (0,05 секунды):

SELECT title 
FROM movies 
LIMIT 150000, 50000 
+0

Из-за 'предела'. Механизм базы данных должен пройти 150 000 строк. –

+0

@GordonLinoff на самом деле ограничение 50000 – Ormoz

+0

Я согласен, что 'LIMIT' также является частью замедления, но время, которое он принимает, смешно, особенно когда вы поднимаете смещение на что-то вроде' 500000' (которое увеличивает время до 30 секунд на запрос). Каковы некоторые решения для его ускорения? –

ответ

0

Проблема с производительностью является смещением значение, выраженное в предложении limit. Если вы читаете через таблицу, то вы можете сохранять значения и использовать > перед order by:

select title 
from movies 
where title > $title 
order by title 
limit 50000; 

Если $title этого названия в строке 150000, то это должно идти быстро. Основываясь на результатах этого запроса, вы выполните сброс $title для следующего запроса.

Я удивлен, что относительно немного строк занимает десятки секунд. Он должен идти быстрее, когда индекс находится в памяти. Еще одним осложняющим фактором является то, что title может быть длинным - поэтому индекс может занимать много десятков или сотен мегабайт. Это все еще не , что большой, но это означало бы заметную задержку.

2

Редактировать: префикс index - лучшее имя, чем частичный индекс, который я использовал.

Поскольку ваш индекс является частичным индексом, MySQL не может использовать его для заказа и все же должен сортировать значения по их полной длине.

Давайте попробуем этот небольшой пример:

create table o1 (a varchar(10)); 

insert into o1 values('test1'),('test2'),('test3'),('tes1'); 
create index oindex on o1 (a); 
explain select a from o1 order by a; 

MySQL использует индекс для заказа по.

 # id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra 
    '1', 'SIMPLE', 'o1', 'index', NULL, 'oindex', '103', NULL, '8', 'Using index' 

Теперь, воссоздают частичный индекс:

drop index oindex on o1; 
create index oindex on o1 (a (2)); 
explain select a from o1 order by a; 

MySQL теперь пытается "FileSort".

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra 
'1', 'SIMPLE', 'o1', 'ALL', NULL, NULL, NULL, NULL, '8', 'Using filesort' 

Для поиска, частичный индекс является полезным, поскольку MySQL может просто отбросить эти значения не полностью удовлетворяют заданному условию. Для ORDER BY MySQL может не иметь такой удачи. В приведенном выше случае даже я создаю «частичный индекс» для макс. длина столбца, MySQL все еще не использует индекс для ORDER BY.

0

Чтобы найти что-то вроде title, вам было бы намного лучше использовать FULLTEXT и MATCH(...) AGAINST(...).

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