Лучший способ поиска в таблице и получения результатов и количества результатов (MySQL)
-
02-07-2019 - |
Вопрос
У меня есть таблица «элементов» и таблица «ключевых слов элемента».Когда пользователь выполняет поиск по ключевому слову, я хочу предоставить ему одну страницу результатов плюс общее количество результатов.
В настоящее время я делаю (для пользователя, который ищет «ab c»:
SELECT DISTINCT {fields I want} FROM itemkeywords JOIN items
WHERE (keyword = 'a' or keyword='b' or keyword='c'
ORDER BY "my magic criteria"
LIMIT 20.10
а затем я делаю тот же запрос со счетчиком
SELECT COUNT(*) FROM itemkeywords JOIN items
WHERE (keyword = 'a' or keyword='b' or keyword='c'
Это может привести к получению довольно большой таблицы, и я считаю, что это решение очень отстойное...
Но я не могу придумать ничего лучше.
Очевидная альтернатива избежать двойного обращения к MySQL, которая выполняет только первый запрос без предложения LIMIT, а затем переходит к правильной записи, чтобы показать соответствующую страницу, а затем к концу набора записей, чтобы подсчитать результат. еще хуже...
Есть идеи?
ПРИМЕЧАНИЕ:Я использую ASP.Net и MySQL, а не PHP.
Решение
Добавьте SQL_CALC_FOUND_ROWS после выбора в вашем ограниченном выборе, затем выполните «SELECT FOUND_ROWS()» после завершения первого выбора.
Пример:
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
Другие советы
Если вы действительно беспокоитесь о производительности и в конечном итоге вам нужно выполнить два запроса, вы можете рассмотреть возможность кэширования общего количества совпадений, поскольку оно не изменится по мере того, как пользователь просматривает страницы результатов.
У вас есть 2 варианта:
MySQL API должен иметь функцию, возвращающую количество строк.Используя старый API, это mysql_num_rows().Это не сработает, если вы используете небуферизованный запрос.
Более простой метод может заключаться в объединении обоих ваших запросов:
SELECT DISTINCT {fields I want}, count(*) as results
FROM itemkeywords JOIN items
WHERE (keyword = 'a' or keyword='b' or keyword='c'
ORDER BY "my magic criteria"
LIMIT 20.10
Я провел несколько тестов и обнаружил, что предложение ограничения не влияет на функцию count(*).Я бы проверил это с DESCRIBE
первый.Я не знаю, насколько это повлияет на скорость вашего запроса.Запрос, который должен дать только первые 10 результатов, должен быть короче, чем тот, который должен найти все результаты для счетчика, а затем первые 10., но здесь я могу ошибаться.
Вы можете посмотреть MySQL SQL_CALC_FOUND_ROWS
в вашем первом утверждении, за которым следует второе утверждение SELECT FOUND_ROWS()
что, по крайней мере, не позволяет вам выполнять два запроса к данным, но все равно будет иметь тенденцию выполнять сканирование всей таблицы один раз.
Видеть http://dev.mysql.com/doc/refman/5.0/en/select.html иhttp://dev.mysql.com/doc/refman/5.0/en/information-functions.html
Лучше рассмотреть:ты Действительно нужна эта функция?