Mysql-запрос выполняется очень медленно при использовании order by - PullRequest
2 голосов
/ 27 декабря 2011

Следующий запрос занимает 30 секунд для завершения при наличии заказа на. Без ордера по нему финиш за 0.0035 секунд. У меня уже есть индекс по полю "имя". Поле «id» является первичным ключом. У меня есть 400 000 записей в этой таблице. Помогите, пожалуйста, что не так с запросом при использовании заказа по.

SELECT * 
FROM users 
WHERE name IS NOT NULL 
AND name != '' 
AND ( status IS NULL OR status = '0' ) 
order by id desc 
limit 50

Обновление: (решение в конце) Привет всем, спасибо за помощь. Ниже приведены некоторые обновления, как вы просили:

  1. Ниже приведен результат объяснения.

    id select_type тип таблицы возможный_ключ ключ key_len ref строки Extra

    1 ПРОСТЫЕ имя диапазона пользователей имя 258 NULL 226009 Использование где; Использование сортировки файлов

  2. Да, в этой таблице около 20 полей.

  3. Ниже приведены индексы, которые у меня есть:

    Поле имени типа Keyname

    PRIMARY PRIMARY 418099 id имя ИНДЕКС 411049 имя

Решение: Оказывается, поля с нулевыми значениями являются причиной. Когда эти 2 поля в условии where имеют значение NOT NULL, это просто займет .000x секунд. Но странно то, что он увеличивается до 29 секунд, если я создаю индекс (status, name, id DESC) или (status, name, id).

Ответы [ 2 ]

5 голосов
/ 27 декабря 2011

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

Предложение OR не совсем подходит для индекса, поэтому, если вы можете, я рекомендую установить status в NOT NULL . Я предполагаю, что NULL не имеет никакого другого значения от нулевого числа. Это очень поможет на самом деле использовать индекс.

Я не знаю, насколько оптимизирован name != ''. Семантически равным будет name > '' (что означает, что это позже в алфавите), возможно, это также сэкономит вам некоторые циклы ЦП.

Затем вы должны решить, в каком порядке будут отображаться ваши столбцы. Эмпирическое правило может быть количество элементов , возможные значения, которые может иметь поле.

Под этим:

ALTER TABLE users ADD INDEX order1 (status, name, id DESC);

Редактировать

Вам не нужно удалять индексы. MySQL очень быстро выберет лучший и проигнорирует все остальное. Они стоят только дисковое пространство и некоторые циклы ЦП на UPDATE с. Но если они вам не нужны ни при каких обстоятельствах, вы, конечно, можете их удалить.

Долгое время связано с медленным доступом к вашему столу. Вероятно, это вызвано полями динамической длины, такими как TEXT или BLOB. Если они вам ВСЕГДА не нужны, вы можете переместить их на двойной вспомогательный стол, например:

users (id, name, status, group_id)
profile (user_id, birthdate, gender, motto, cv)

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

Edit2

Вы указываете MySQL, какой индекс использовать, указав его (или более), например:

SELECT id, name FROM users USE INDEX (order1) WHERE name != '' and status = '0' ORDER BY id DESC
0 голосов
/ 27 декабря 2011

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

попробуйте сделать:

explain SELECT * 
FROM users 
WHERE name IS NOT NULL 
AND name != '' 
AND ( status IS NULL OR status = '0' ) 
order by id desc 
limit 50

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

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