программно заменить поля SELECT в SQL-запросе, чтобы определить количество результатов - PullRequest
0 голосов
/ 15 июля 2009

Учитывая любой запрос (группировка, объединения и подзапросы возможны в любой комбинации), я хотел бы разбить его на нумерацию страниц как можно более эффективно. Прямо сейчас я просто запускаю запрос, затем подсчитываю количество строк, возвращаемых в PHP, выясняю, сколько страниц данных, отображаю те, которые идут на текущей странице, и выводю правильные ссылки на другие страницы.

Мне кажется, что потенциально очень большой набор результатов из запроса, однако, в основном тратится впустую. Есть ли способ выполнить запрос дважды, когда в первый раз вы выбираете COUNT (*), чтобы получить одно число со строками для разбивки на страницы, и во второй раз, когда вы запускаете исходный запрос с надлежащими ограничениями на основе страницы, просматриваемой в данный момент? Будет ли это значительно меньше налогов на сервер базы данных?

Для тривиального запроса это не проблема ... замените все после SELECT и до WHERE на count (*). Однако это не работает, если в запросе есть группировка, так как вы получите количество в каждой группе, а не общее количество строк. Если вы группируете по столбцам a, b и c, правильно ли выбрать счетчик (отличный от a, b, c)? Нужно ли что-то особенное для обработки подзапросов?

Ответы [ 5 ]

4 голосов
/ 15 июля 2009

Вы можете использовать SQL_CALC_FOUND_ROWS , чтобы получить небольшой набор результатов, но MySQL также может рассчитать размер неограниченного набора результатов:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name LIMIT 10;

SELECT FOUND_ROWS();
3 голосов
/ 15 июля 2009

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

select count(*)
from (<original select query>)
2 голосов
/ 15 июля 2009

Вы можете попросить mySQL рассчитать количество строк, которые были бы возвращены без предложения limit, используя SQL_CALC_FOUND_ROWS.

Это даст вам первую страницу из 20:

SELECT SQL_CALC_FOUND_ROWS * FROM table LIMIT 0,20

Затем вы можете запросить количество строк, которые были бы возвращены без SQL_CALC_FOUND_ROWS:

SELECT FOUND_ROWS() AS numrows

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

2 голосов
/ 15 июля 2009

Это может помочь: mysql имеет limit feature:

select * 
from mytable
limit 10,40

Где предел 10,40 означает, что даст мне 40 результатов, начиная с результата 10 (который основан на 0).

Вы можете построить нумерацию страниц по этой функции. В приведенном выше примере 40 означает 40 результатов / стр.

0 голосов
/ 15 июля 2009

Я бы немного поэкспериментировал в вашей среде разработки, чтобы увидеть, есть ли какое-то преимущество в производительности.

Вы можете ограничить возвращаемый результат на основе количества записей на страницу, используя предложение LIMIT, как предлагает MercerTraieste, однако теперь вы совершаете поездку в базу данных на страницу, чего обычно следует избегать. Я предполагаю, что ваш PHP-скрипт использует курсор для получения данных с сервера MySQL, и я полагаю, что курсор остается открытым для извлечения этих данных для других ваших страниц. Выполняя LIMITed-запросы, вы на самом деле можете облагать налогом сервер базы данных больше . Конечно, я бы протестировал / поэкспериментировал, чтобы выяснить, отслеживая загрузку базы данных с помощью инструмента мониторинга производительности MySQL, если таковой имеется.

Вам, вероятно, даже не нужно будет делать СЧЕТ (*) для разбивки на страницы, просто определите, сколько записей вы хотите на странице, и просто верните их, начиная с разных результатов.

То есть, делать (psuedocode следует)

SELECT <columns> FROM <table> LIMIT <records-per-page>;
while (More data available for future pages)
{
    records-shown += records-per-page;
    SELECT <columns> FROM <table> LIMIT <records-per-page>,<records-shown>;
}

По общему признанию, другие способы сделать это, вероятно, чище.

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