Лучший способ поиска в таблице и получения результатов и количества результатов (MySQL)

StackOverflow https://stackoverflow.com/questions/146212

Вопрос

У меня есть таблица «элементов» и таблица «ключевых слов элемента».Когда пользователь выполняет поиск по ключевому слову, я хочу предоставить ему одну страницу результатов плюс общее количество результатов.

В настоящее время я делаю (для пользователя, который ищет «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

Лучше рассмотреть:ты Действительно нужна эта функция?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top