|
|
|
| Доброй ночи!
Все не могу сделать выбор между двумя стандартными ситуациями для пагинации
Вариант1:
1) SELECT COUNT(*) .... - получили кол-во записей
2) SELECT ... LIMIT - получили лимитированное количество записей
Вариант2:
1) SELECT SQL_CALC_FOUND_ROWS * ... LIMIT - получили лимитированное количество записей
2) SELECT FOUND_ROWS() - получили кол-во записей
http://softtime.ru/forum/read.php?id_forum=3&id_theme=49177
Тут об этом говорилось, но на каком-то уровне не том
Вопрос в чем - для MyISAM насколько я понимаю разница между двумя вариантами будет невелика, поскольку запрос COUNT(*) будет дешевым. А вот для других таблиц уже будет что-то иначе. Вопрос - будет ли?
Хотелось бы услышать комментарий cheops'а или Трианона... Если можно | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 00:40)
| | COUNT(*) дешев если не требуется перебора таблицы, если у вас отсутствует условие WHERE, особенно, если в условии используются неиндексированные столбцы. | |
|
|
|
|
|
|
|
для: cheops
(08.10.2009 в 00:48)
| | Ага, т.е. если в WHERE стоят неиднексированные столбцы, то использовать COUNT(*) не рекомендуется? Это касается только MyISAM или всех таблиц?
А что насчет InnoDB? ПРосто насколько я помню в ней использование COUNT(*) вобще физически противопоказано... Или нет? | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 00:40)
| | Трудоемкость запроса SELECT COUNT(*) зависит не столько от типа таблицы, сколько от того, какими условиями он нафарширован. А ведь внутри SELECT может быть довольно сложный запрос. Может и не быть.
В некоторых случаях агрегатный запрос SELECT COUNT(*) адекватный исходному, просто крайне тяжело составить.
Опять же если таблица относительно короткая (тысячи .. десятки тысяч строк) - ситуация одна.
Если достаточно длинная (десятки ... сотни миллионов строк) - несколько другая.
А выбирать всё равно Вам. Однозначного ответа нет. | |
|
|
|
|
|
|
|
для: Trianon
(08.10.2009 в 00:51)
| | Немного не понял наверное ваш комментарий. В общем случае да, запросы сложные.. И 2 раза писать одно и то же (я о варианте1) удручает.
Еще вопрос - в чем разница между таблицей с десятками тысяч строк и таблицей с миллионами? Просто я пока работаю (в основном) с таблицами с сотнями тысяч записей... Как раз на перепутье :) | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 00:56)
| | По поводу InnoDB - то что я и говорил. Надо просто понимать суть.
http://denis.boltikov.ru/2008/03/12/count-dlya-tablic-innodb-perevod-s-mysql-performance-blog/
>И 2 раза писать одно и то же (я о варианте1) удручает.
Ну иногда исходный SELECT-запрос сам по себе агрегирующий. И натягивать на него сверху COUNT(*) - неминуемый сложный запрос с непонятно каким планом... короче, SQL_CALC_FOUND_ROWS - сильно приманивает.
C другой, SQL_CALC_FOUND_ROWS будет заставлять сервер генерировать все строки результата, в том числе и после конца запрошенного LIMIT-диапазона - просто выводить их клиенту не будет.
И если строк ОЧЕНЬ много, то...
А Вам проще сравнить бенчмарки. | |
|
|
|
|
|
|
|
для: Trianon
(08.10.2009 в 01:03)
| | > короче, SQL_CALC_FOUND_ROWS - сильно приманивает.
вот-вот, я о том же
> C другой, SQL_CALC_FOUND_ROWS будет заставлять сервер генерировать все строки результата, в том числе и после конца запрошенного LIMIT-диапазона - просто не выводить их клиенту не будет.
оО вот отсюда поподробнее.... т.е. по сути SQL_CALC_FOUND_ROWS просто делает полный селект, а пользователю выдает обрубленную его часть??? Не верю... Тогда же теряется вся его суть!..
С бенчмарками да, было бы хорошо, но у меня под рукой ненастроенные таблицы InnoDB и обыкновенно используемые MyISAM. В то же время понимаю, что уходить с MyISAM нужно. Потому у меня бенчмарки будут не особенно стоящими, а вот других пока не видел | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 01:07)
| | >.е. по сути SQL_CALC_FOUND_ROWS просто делает полный селект, а пользователю выдает обрубленную его часть???
Это свойство вовсе не SQL_CALC_FOUND_ROWS
Это свойство LIMIT в принципе.
Правда простой LIMIT, дойдя до конца диапазона, всё же затыкается.
А считающий - шлёпает дальше. | |
|
|
|
|
|
|
|
для: Trianon
(08.10.2009 в 01:11)
| | Мде.... Можно тогда я приведу пример?
Есть таблица со 100 записями
2 запроса
1) SELECT * FROM table WHERE ... LIMIT 10,10
2) SELECT * FROM table WHERE ... LIMIT 60,10
Получается при использовании SQL_CALC_FOUND_ROWS первый запрос работает намного дольше второго? | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 01:23)
| |
gen - время формирования и сортировки строк
out - время выдачи строк клиенту
SELECT * FROM tbl_100 | обычный | с SQL_CALC_FOUND_ROWS
----------------------+----------------------+----------------------
WHERE ... LIMIT 10,10 | gen*(10+10) + out*10 | gen*100 + out*10
WHERE ... LIMIT 60,10 | gen*(60+10) + out*10 | gen*100 + out*10
|
| |
|
|
|
|
|
|
|
для: Trianon
(08.10.2009 в 10:23)
| | Можно если не трудно пруфлинк? Или это ваш бенч? | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 11:27)
| | Это лично мое | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 01:07)
| | >В то же время понимаю, что уходить с MyISAM нужно.
Можно потерять в скорости и много... MyISAM проще, но быстрее. | |
|
|
|
|
|
|
|
для: cheops
(08.10.2009 в 01:12)
| | Насколько я понимаю, у MyISAM очень большое количество недостатков (навскидку только приведу отсутствие блокировок и транзакций), которых нет в других СУБД (PostgreSQL) или таблицах (InnoDB). InnoDB насколько я помню тоже не считается идеальной?.. Тогда в какую сторону следует смотреть? | |
|
|
|
|
|
|
|
для: 1999
(08.10.2009 в 01:25)
| | От задачи зависит, например, тут на форуме транзакции вообще не нужны, если вы работаете толстым клиентом с базой данных, хранящей реальные депозиты - наплевать на всю скорость, лучше сервер помощнее купить, чем отказываться от транзакций.
Это как при выборе языка программирования - лучше выбирать тот язык, который больше всего подходит для решения задачи, а не тот, который лучше всего знаешь. | |
|
|
|