Простой SQL-запрос занимает в 10-20 раз больше с "ORDER BY" - PullRequest
0 голосов
/ 29 января 2019

Простой запрос SQL занимает от 10 до 20 раз дольше с "ORDER BY".Как я могу ускорить его?

Мой первый запрос был:

SELECT * 
FROM wp_usermeta 
WHERE meta_key = 'partner' 
AND meta_value = 1 
ORDER BY user_id DESC
LIMIT 5

Это занимает 0,2601 секунды.После некоторых исследований я мог бы оптимизировать его до:

SELECT user_id 
FROM wp_usermeta 
WHERE meta_key = 'partner' 
AND meta_value = '1' 
ORDER BY umeta_id DESC
LIMIT 5

Этот запрос занимает всего 0,1491 секунды, но все же слишком много.Если я удаляю ORDER BY, это займет всего 0,0075 секунды.

Я много читал на Stackoverflow и других форумах, но не смог получить лучшего результата.У кого-нибудь есть идеи?

Это стандартная таблица WordPress usermeta.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

WP имеет неэффективную схему для своих «мета» таблиц.Но они могут быть исправлены.В [ здесь ] я обсуждаю несколько вещей, которые необходимо исправить.И я объясняю 191 клудж, плюс 5 вариантов его избежания.

И я не попадаю в «пересечение слиянием индекса», поскольку составной индекс всегда (?) Лучше.

0 голосов
/ 29 января 2019

Таблица wp_usermeta в WordPress хорошо известна и имеет индекс в один столбец для meta_key.

Но при этом выбирается все строк с указанным ключом, что не 'Сузить поиск сильно.Также это не помогает сортировке, поэтому запрос должен выполнить дополнительную работу для сортировки:

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = 1  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key
          key: meta_key
      key_len: 767
          ref: const
         rows: 1
        Extra: Using where; Using filesort

Добавление нового индекса должно помочь:

mysql> alter table wp_usermeta add key (meta_key(191), meta_value(191), user_id);

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = 1  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key_2,meta_key
          key: meta_key_2
      key_len: 767
          ref: const
         rows: 1
        Extra: Using where; Using filesort

Даже если это показывает, чтоиспользуя новый индекс (meta_key_2), это не помогает.key_len и ref указывают, что он использует только первый столбец индекса.Почему он не может использовать оба столбца?

Поскольку ваш запрос сравнивает целое значение 1 со строковым столбцом meta_value.Вы должны сравнить похожие типы, то есть строку '1' со столбцом строки:

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = '1'  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key_2,meta_key
          key: meta_key_2
      key_len: 1534
          ref: const,const
         rows: 1
        Extra: Using where

Теперь он может использовать второй столбец в индексе для поиска значения '1', вы можете сказать, потому что key_len: 1534 и ref: const,const указывают, что он использует два столбца индекса вместо одного столбца.

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

...