Лучший способ поиска в таблице и получения результатов и количества результатов (MySQL) - PullRequest
3 голосов
/ 28 сентября 2008

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

Что я сейчас делаю (для пользователя, который ищет "a b 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

Ответы [ 4 ]

5 голосов
/ 28 сентября 2008

Добавьте 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();
1 голос
/ 10 ноября 2008

Если вы действительно беспокоитесь о производительности и вам в конечном итоге нужно сделать два запроса, вы можете рассмотреть возможность кэширования общего количества совпадений, поскольку это не изменится, когда пользователь просматривает страницы результатов. 1001 *

0 голосов
/ 28 сентября 2008

Вы можете посмотреть на MySQL SQL_CALC_FOUND_ROWS в своем первом операторе, за которым следует второй оператор SELECT FOUND_ROWS(), который, по крайней мере, мешает вам выполнить 2 запроса данных, но все равно будет стремиться выполнить сканирование всей таблицы один раз.

См. http://dev.mysql.com/doc/refman/5.0/en/select.html и http://dev.mysql.com/doc/refman/5.0/en/information-functions.html

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

0 голосов
/ 28 сентября 2008

У вас есть 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 (*) не влияет предложение limit. Я бы сначала проверил это с DESCRIBE. Я не знаю, насколько это повлияет на скорость вашего запроса. Запрос, который должен дать только первые 10 результатов, должен быть короче, чем запрос, который должен найти все результаты для подсчета, а затем первые 10. Но я могу ошибаться.

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