Контекст: это база данных MySQL для проекта B2C.
Я использую предложение SELECT COUNT (), чтобы заранее узнать количество строк, которые вернет обычный SELECT. Это только для расчетов нумерации страниц в графическом интерфейсе. Проблема, с которой я столкнулся, заключается в том, что просто в локальной настройке моего ноутбука продолжительность запроса SELECT COUNT () находится в опасном порядке 1 с по сравнению с запросом SELECT, который находится в порядке 1 мс. Примерно в 1000 раз медленнее !!
Я изолировал проблему и создал отдельный проект, чтобы иметь простой тестовый стенд. Таблица документ была создана следующим образом:
drop table document;
create table document (
id int primary key auto_increment,
brand varchar(128) not null,
ref varchar(32) not null,
title varchar(128) not null,
brief varchar(256) not null,
content mediumtext not null,
fulltext key (brand, ref, title, brief, content)
);
Чтобы создать модель реальной проблемы, я заполнил таблицу 2000 случайными текстовыми строками, имеющими марка и ссылка 1 слово, заглавие 6 слов, краткий 12 слов и содержание около 50 килобайт в словах.
Типичный пользовательский запрос выглядит примерно так:
select id, brand, ref, title, brief, content from document
where match (brand, ref, title, brief, content) against ('espadas' in boolean mode)
limit 24
поэтому запрос COUNT () должен быть:
select count(id)
from document
where match (brand, ref, title, brief, content) against ('espadas' in boolean mode)
Используя локальную настройку на моем ноутбуке, эмпирическая продолжительность регулярных запросов составляет 1-3 мс, что для меня достаточно. Я был готов к еще более длительным срокам, имея в виду ценность поиска FULLTEXT / MATCH для пользователя. Количество запросов Count () увеличивается до 1 с - это огромное время, которое ведет к более высокому риску даже при низкой параллельности.
Есть идеи, как уменьшить эту длительную продолжительность SELECT COUNT ()?
Версия MySQL: 10.1.10-MariaDB, а таблица документов - InnoDB.
Хороший замечание, Роланд Старк, я забыл прокомментировать, что количество строк, подсчитанных для слова «espadas», составляет 555 из общего количества строк в 2000. Так что нет ничего страшного в том, чтобы потратить 1 с.
Я только что проверил в своей системе, счет занимает 0,000 секунд, а 24 строки - 0,015 секунды. В качестве содержания я скопировал сюда половину вашего вопроса.
Не могли бы вы подробно рассказать о версии MySQL?
Если подсчет занимает на порядки больше времени, почему бы не запустить запрос SELECT
, а затем подсчитать возвращаемые результаты, используя любой язык, который вы используете для обработки данных в графическом интерфейсе, вместо выполнения запроса предварительной выборки. а затем запрос на выборку?
Возможно, это может быть идеей даже для 2000 строк, Джон, но с загрузкой 50 Кбайт в столбце содержимого, я думаю, это не лучшее решение. 50k x 2k = 100 МБ в худшем случае и 50 МБ в среднем.
Здесь важен контекст: вы можете выбрать решение методом перебора для локального приложения, но для архитектуры B2C каждую лишнюю миллисекунду нужно умножать на количество одновременно работающих пользователей, чтобы не испортить задержку обслуживания. Роланд Старке показал некоторые результаты, которые соответствуют моим ожиданиям. Может быть, это проблема моей текущей версии, которая была исправлена в более поздних версиях MySQL?
Хорошо, ребята. Как я и предполагал по результатам Роланда Старка, это была проблема версии. Несмотря на то, что я использовал термин «MySQL» в заголовке и тегах, я использовал MariaDB 10.1.10, как я понял в последней строке моего вопроса. Я только что установил MySQL 8, и результаты ожидаемые: ~ 2,4 мс для выбора и ~ 1,3 мс для счетчика выбора. Спасибо за идеи и предложения.
Некоторые несоответствия связаны с кешем запросов. Повторите ваши временные тесты следующим образом: SELECT SQL_NO_CACHE ...
. Примечание: MySQL 8 избавился от кеша запросов.
Спасибо @ rick-james. Это хорошее объяснение того, почему он отлично работал в MySQL 8!
Есть более 24 результатов? После этого первый запрос может остановиться. Запрос счета должен продолжаться, поэтому он медленнее. (У меня нет решения.)