WedX - журнал о программировании и компьютерных науках

Очень медленный запрос с ORDER BY и LIMIT

У меня очень медленный запрос, потому что я использую ORDER BY. Теперь я понимаю, почему это медленно, но я понятия не имею, как сделать это быстрее.

В таблице было около 900 000 записей. (причина, почему это медленно)

SELECT SQL_NO_CACHE id, name 
FROM users where is_provider = 0 
AND activated_at IS NOT NULL
AND is_ngo = 0 
AND deleted_at is NULL 
AND is_cancelled = 0   
ORDER BY name 
LIMIT 60000, 90;

Я использую лимит, потому что я использую разбиение на страницы. SQL_NO_CACHE, потому что я не хочу использовать кеш для тестирования.

Этот запрос занимает около 60 секунд, что слишком долго. Это фоновая задача, поэтому, если я смогу повторить ее за 5 секунд, все будет в порядке.

У меня есть индексы для столбца activ_at иDeleted_at, которые являются полями времени. Остальные являются логическими, поэтому индексы не нужны.

Спасибо

09.03.2011

Ответы:


1

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

EXPLAIN SELECT SQL_NO_CACHE id, name 
FROM users where is_provider = 0 
AND activated_at IS NOT NULL
AND is_ngo = 0 
AND deleted_at is NULL 
AND is_cancelled = 0   
ORDER BY name 
LIMIT 60000, 90;

Как подробно описано в этой очень старой, но полезной статье:
https://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm

09.03.2011
  • Для всех, кто читает этот ответ: я не нашел статью полезной. Короче говоря, если вы не новичок в MySQL и еще не добавили индекс, я бы продолжал искать ваш ответ. 28.02.2013

  • 2

    Эта статья может оказаться полезной: https://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/

    Он имеет дело с комбинацией ORDER BY и LIMIT.

    11.08.2011
  • Я думаю, что виновато большое смещение LIMIT. Как поясняется в статье, было бы лучше преобразовать приведенный выше запрос в запрос where CONDITION, потому что тогда поиск внутри любого фрагмента займет постоянное время. 22.12.2011

  • 3

    Я предполагаю, что именно упорядочение по имени делает его медленным.

    Для проверки удалите предложение ORDER и проверьте, сколько времени это займет.

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

    09.03.2011
  • Спасибо за быстрый ответ. Да, у меня есть индекс имени. Проблема в том, что мне нужен заказ по имени... 09.03.2011

  • 4

    Я бы предложил добавить индекс для наиболее селективного логического поля, т. е. если только 5% строк в БД имеют is_provider = 0, то вы можете значительно сократить количество строк, которые вам нужно сканировать для других свойств. Если распределение 50/50, в этом нет особого смысла, но я бы посмотрел на распределения и позволил вам определить, какие индексы могут быть полезны. Конечно, вы должны ориентироваться на фактическую производительность (в том числе и на другие запросы, которые могут у вас возникнуть).

    09.03.2011
  • Спасибо за Ваш ответ. Я играл с индексами, но поставить их или удалить не имеет никакого значения 09.03.2011
  • @Michael, вы пробовали составной индекс, включающий имя? Следует сократить время, необходимое для сортировки. Вы также можете попробовать реструктурировать свой запрос, чтобы помочь ему выбрать правильный индекс, возможно, используя вложенность. 09.03.2011

  • 5

    В качестве альтернативы удалите предложение Order By и выполните упорядочение после прочтения записей. Это возлагает работу на клиента, но это может быть надежнее и быстрее, если ваша база данных медленная (как здесь кажется).

    Ваше здоровье,

    Даниэль

    09.03.2011

    6

    Индексируется ли столбец name как часть другого индекса?

    Упорядочение по индексу должно быть относительно быстрым (нет необходимости в файловой сортировке), если только имя не является частью индекса, а не первой частью. Подробнее см. здесь: https://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

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

    10.03.2011

    7

    Ты можешь попробовать

    SELECT  * FROM (SELECT SQL_NO_CACHE id, name 
    FROM users where is_provider = 0 
    AND activated_at IS NOT NULL
    AND is_ngo = 0 
    AND deleted_at is NULL 
    AND is_cancelled = 0   
    ORDER BY name) t
    LIMIT 60000, 90;
    

    чтобы избежать ORDER BY и LIMIT вместе.

    09.01.2014

    8

    Проблема здесь в том, что Mysql сначала пытается Order By все строки, доступные в таблице, с помощью Name, а затем пытается выбрать запись на основе условия Where. Итак, что вы можете попробовать, это сначала Select записи на основе Where условия и запустить Order By name на наборе результатов.

    Пример:

    SELECT  * FROM (SELECT SQL_NO_CACHE id, name 
    FROM users where is_provider = 0 
    AND activated_at IS NOT NULL
    AND is_ngo = 0 
    AND deleted_at is NULL 
    AND is_cancelled = 0) t ORDER BY name
    LIMIT 60000, 90;
    
    24.09.2020
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

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

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]