Оптимизировать SELECT ... ГДЕ В (...) - PullRequest
2 голосов
/ 26 сентября 2011

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

Для этого я использую следующую команду:

SELECT * FROM  products
WHERE  prodid in (10331,11639,12127..) ORDER BY Field(prodid, 10331,11639,12127...);

Последовательность может состоять из 20 идентификаторов.У prodid есть индекс b-дерева.

Это очень частый запрос, и я пытаюсь найти способы улучшить производительность этой части системы.Теперь среднее время для этого запроса составляет 0,14-0,2 сек. Я бы хотел уменьшить время до 0,01-0,05 сек.

Каков наилучший способ сделать это?Хэш-индекс MySQL, хранить идентификатор продукта в memcached или что-то еще?

Ответы [ 3 ]

1 голос
/ 26 сентября 2011
SELECT * FROM  products                         <<-- select * is non-optimal
WHERE  prodid in (10331,11639,12127..) 
ORDER BY Field(prodid, 10331,11639,12127...);   <<-- your problem is here

Сначала поместите указатель на prodid см. Ответ Энтони.

Чем изменить запрос следующим образом:

SELECT only,the,fields,you,need FROM  products
WHERE  prodid in (10331,11639,12127..) 
ORDER BY prodid

Если вы убедитесь, что ваш список IN отсортирован по возрастанию, прежде чем предлагать его в предложение IN, order by prodid приведеттот же результат als order by field(...

  • Использование функции вместо поля убивает любой шанс использования индекса, вызывая медлительность.
  • select * будет получать данные, которые вам могут не понадобиться, вызывая дополнительный доступ к диску, а также дополнительное использование памяти и дополнительный сетевой трафик.
  • На InnoDB, если вы только select проиндексировали поля, MySQL никогда не будет читать таблицу, а только экономит время индекса (в вашем случае это, вероятно, не проблема)

Каков наилучший способ сделать это?Хэш-индекс MySQL, хранить идентификатор продукта в memcached или что-то еще?

Есть несколько приемов, которые вы можете использовать.

  • Если таблица продуктов не слишком велика, вы можете сделать ее таблицей memory, которая хранится вБАРАН.Не делайте этого для больших таблиц, это замедлит другие вещи.
    Вы можете использовать hash индексы только для таблиц памяти.
  • Если продикты непрерывны, вы можете использовать BETWEEN 1000 AND 1019 вместоIN (1000, 1001 ..., 1019)
1 голос
/ 26 сентября 2011

Вы можете попытаться создать объединение результатов:

SELECT * FROM  products WHERE prodid = 10331
UNION ALL
SELECT * FROM  products WHERE prodid = 11639
UNION ALL
.
.
UNION ALL
SELECT * FROM  products WHERE prodid = 12127
0 голосов
/ 26 сентября 2011

Вы можете попробовать поместить индекс в столбец prodid, используя следующий запрос:

CREATE INDEX index_name
ON products (prodid); 

Для получения дополнительной информации прочитайте это сообщение.

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