За последние 24 часа нас посетили 22638 программистов и 1013 роботов. Сейчас ищут 659 программистов ...

COUNT vs SQL_CALC_FOUND_ROWS

Тема в разделе "Прочее", создана пользователем mpak, 30 июл 2010.

Статус темы:
Закрыта.
  1. mpak

    mpak Активный пользователь

    С нами с:
    30 окт 2006
    Сообщения:
    440
    Симпатии:
    0
    Делать подсчет количества записей в таблице отдельным запросом нецелесообразно.
    "SELECT * FROM `table`"
    "SELECT COUNT(*) FROM `table`"

    Лучше использовать
    "SELECT SQL_CALC_FOUND_ROWS * FROM `table`"
    "SELECT FOUND_ROWS()"

    Второй вариант побыстрее так как в mysql количество записей на момент запуска второго запроса уже подсчитано. База просто возвращает результат работы предыдущего запроса.
     
  2. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Дуд, а на вложенных селектах не бочинит?
     
  3. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    дальше зубри теорию и не пиши глупости.
     
  4. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    Koc
    попробуй :)

    я хз, у меня пока не попадалось проблем, тут видишь ли стоит фильтр на стоп слова, в принципе можно над ним поработать - когда нарвусь на задницу, то поправлю :)
     
  5. mpak

    mpak Активный пользователь

    С нами с:
    30 окт 2006
    Сообщения:
    440
    Симпатии:
    0
    Подтвердил практическим путем верность своих утверждений.

    Код (Text):
    1. <?
    2.  
    3. echo '<p />';
    4. $time = microtime(1);
    5. for($i=0; $i<1000; $i++){
    6.     mysql_query("SELECT SQL_CALC_FOUND_ROWS * FROM mp_users LIMIT 10");
    7.     mysql_query("SELECT FOUND_ROWS()");
    8. }
    9. echo microtime(1) - $time;
    10.  
    11. echo '<p />';
    12. $time = microtime(1);
    13. for($i=0; $i<1000; $i++){
    14.     mysql_query("SELECT * FROM mp_users LIMIT 10");
    15.     mysql_query("SELECT COUNT(*) FROM mp_users");
    16. }
    17. echo microtime(1) - $time;
    18.  
    19. ?>
    Полученные результаты

    0,37244200706482
    1,2320649623871

    Еще могу дать ссылку на статью где автор также подтверждает мои слова. http://valera.ws/2008.07.24~calc-found- ... ostgresql/

     
  6. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    свое незнание мат части еще раз.

    предположу: используется, структура таблиц - innodb. ну и какбы мне абсолютно пофигу и не надо вас переубеждать в том, что ваш вариант неправильный, юзайте его и живите счастливо :) но почитаете мануал а не всяких "авторов"
     
  7. mpak

    mpak Активный пользователь

    С нами с:
    30 окт 2006
    Сообщения:
    440
    Симпатии:
    0
    Что из мат части мне нежно узнать чтобы начать использовать заранее медленный способ выборки данных? Думаю в других типах таблиц будет то же самое потому что подход остается. При использовании SQL_CALC_FOUND_ROWS фактически запрос не выполняется. Его просто нет. Возвращаются данные полученные в результате выполнения предыдущего запроса. Еще одна статья которая советует использовать конструкцию SQL_CALC_FOUND_ROWS http://ekimoff.ru/173/.
     
  8. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    чиатйте а не думайте

    ага, не спорю

    в статьях таких идиотических надо читать не гавностатью, а комментарии где хорошо распасано что автор - недалекий человек без знания матчасти. комментарии к гавностатье распечатайте и повесьте на стену перед компьютером, чтобы запомнить что так делать нельзя.
     
  9. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    не думайте а читайте или проверяйте, думать вам пока не позволяет теор неподкрепленность. в myisam тип вазпрос на каунт порвет все ваши мысли в пух и прах
     
  10. mpak

    mpak Активный пользователь

    С нами с:
    30 окт 2006
    Сообщения:
    440
    Симпатии:
    0
    Аргументов так и не увидел. А результаты проверки говорят что SQL_CALC_FOUND_ROWS быстрее в три раза
    0,37244200706482 против 1,2320649623871.

    Выбор очевиден.
     
  11. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    все, мне пофиг. вы не знаете разницы этих запросов, отказываетесь почитать. меня этот цирк достал. может когда нить почитаете и поймете свою неправоту, ариведерчи
     
  12. mpak

    mpak Активный пользователь

    С нами с:
    30 окт 2006
    Сообщения:
    440
    Симпатии:
    0
    Выдержка из документации mysql http://www.phpclub.ru/mysql/doc/miscell ... tions.html

    И здесь пишется о том же. SQL_CALC_FOUND_ROWS бустрее.

    Так в чем ты меня убеждаешь? В том что COUNT быстрее? Если даже офф документация говорит об обратном (переведенный ее вариант). Здесь даже обьясняется в чем разница "так как не требуется посылать результат клиенту." И об этом я написал в первых сообщениях, что запрос не выполняется. Резаультаты клиенту не посылаются. Я знаю разницу этих запросов. И понимаю какой из них будет быстрее. Из двух возможных вариантов выбираю наиболее быстрый и удобный. Удобство заключается в том что не приходится два раза задавать условия выборки и ее сортировку.. Когда начинал тоже пользовался COUNT но позже пересмотрел свою позицию.
     
  13. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    мпак ты и не прав и умерь апломб.
     
  14. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    лол, если ты пересмотрел и не начинающий то мне жалко твоих клиентов. читай дальше, проблема глубже и она не в СКОРОСТИ выполнения этого запроса по извлечению переменной.
     
  15. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    тут нет ни слова про count(), а по набору слов остальных видночто это в лучшем случае документация от мускуль4.4, в общем устаревшее гавно. в выделенных мной строках есть великий смысл, который ты не понимешь :)
     
  16. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    phpdude
    в чем соль? лень доку читать ><
     
  17. Ensiferum

    Ensiferum Активный пользователь

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    phpdude
    да скажи уже, что у топикстартера не так
     
  18. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    Ensiferum
    великие маги и волшебники не открывают своих тайн xD
     
  19. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    много не так. например, когда мы делаем

    select * from users limit 10,0

    а записей всего 100 000, то мускуль читать будет все 100 000 чтобы понять сколько их там всего под условия попало. еще знаешь чем плохо? это может вызвать часто temp table, а для таких объемов это губительно.

    select count(*) не делает чтение строчек целиком, он только инкрементирует переменную так сказать. неебическая скорость которую получил тс на ино таблице всего лишь фейк, потому что ино не хранит нигде инфу о колве записей в силу своей архитектуры, myisam хранит кол-во строк в таблице в переменной.

    ну и при индексах(если селект их использует) каунт выполнится быстрее перебора. в общем то надо просто почитать статьи не "почему calc_rows ахуенен?!" а "почему он фигов", там много интересного. эти минусы я помню по памяти, там еще было дофига мелочей я уверен

    на маленьких таблицах калк рулит, и рулит на слоных выборках, где в результате пара десятков строк возвращается. при хороших запросах (которые индексы юзают) рулит каунт это какбы итого в 2 словах. то что для тс рулит калк, гвоорит всего лишь о том, что пишет хуевые запросы и не понимает как оно внутри вариатся, да ему и особо не надо, он лучше статьи дурачков всяких почитает, а не офф документацию :)
     
  20. Ensiferum

    Ensiferum Активный пользователь

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    phpdude
    Познавательно. Спасибо
     
  21. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    Ensiferum
    не за что :)

    мускуль во многом дура, если делать "как пишут", то сервер тебя бы сам выебал во все щели если бы мог ...
     
  22. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    как пишут мЕгАкОдЕрЫ (и хвастаются) ни одна бд не выдержит.
     
  23. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    armadillo
    ага))) тоже всегда лол над всякими "разработчиками кмс")))
     
  24. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    mpak
    COUNT(*) действительно быстрее чем по полю.
     
  25. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Ех, сколько сколько ламеров орут об офигенности CALC_FOUND_ROWS и скольких увольняют за неспособность оптимизировать запросы на базу, потому что они даже не подозревают о том, что проблемы могут быть из-за CALC_FOUND_ROWS :D

    Дам вам совет, как нужно протестировать, что бы вы поняли где есть проблемы:
    Сделайте 3-4 связанных таблицы, нагоните в базу 2-3 ГБ данных с большим кол-вом строк (хотя-бы по 200-300 тысячь на таблицу и с достаточно большой рандомностью) и поделайте разные запросы от простых SELECT с простыми WHERE, потом посложнее с JOIN ну и какой-нить агрегированный запрос со сложными условиями. А потом попробуйте с помощью документации, логики и гугла объяснить почему вы получили результаты, которые не сходятся с вашими текущими утверждениями.

    Я ответы все эти знаю, но вы сами исследуйте вопрос, поскольку вы всё равно упёрлись и пока своими руками не проверите, будете упёртым бараном и тыкать нас в мануал. Мануал всё правильно пишет, но он описывает конкретную фитчу, он не учитывает её использование в разных ситуациях, к каким проблемам это может привести в реальном приложении, когда база постепенно вырастает. В начале будет всё хорошо, зато потом...

    Сам я лично сталкивался с этим на работе при базе в 6 гигов и большим кол-вом запросов (социальная сеть) и поверьте мне - SQL_CALC_FOUND_ROWS там используется лишь в нескольких местах, и не от хорошей жизни, ибо писать все эти SELECT COUNT(*) FROM table WHERE ..... не самое увлекательное дело.
     
Статус темы:
Закрыта.