|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Это копия аналогичной темы из подфорума по MySQL, т.к., возможно, причина проблемы кроется в PHP-части. Если кратко: есть php-скрипт, в числе функций которого добавление новой записи в таблицу (или же обновления существующей, если запись для данного пользователя уже есть). В боевом режиме функция может дёргаться примерно 50 раз в секунду, при этом скорость добавления записей достигает максимум 5 в секунду, т.е. добавление 7500 записей закончится только через неприличные 25 минут. select-запросы из той же таблицы выполняются за приемлемое время. Структура таблицы – 4 поля: одно int(11), одно datetime и два varchar длиной 10 и 32, последний из которых primary index (кривоватый момент, но, судя по всему, он бы скорее влиял на скорость выборки). InnoDB. Как видно из кода ниже, сам запрос тоже довольно простой. Пока не могу понять, лежит ли причина в php или mysql-части. Явно что-то не так. Пробовал менять innodb_flush_log_at_trx_commit на 0 и 2 (настройка в MySQL), ощутимой разницы не дало. Использование в php постоянных кэшируемых соединений помогло предотвратить перегрузки сервера, имевшие место ранее при подобных нагрузках. Самый частый ответ на подобный вопрос – объединять insert-запросы в один, но, как было упомянуто ранее, все данные приходят от разных пользователей, и мой нубский мозг не может пока представит, возможно ли вообще объединение инсертов в этой ситуации. php-код: Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.
Буду рад любой помощи. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 10:31 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Надо смотреть в что сервер упирается. Скорее всего затык на COUNT(*) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 11:04 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
HettСкорее всего затык на COUNT(*)Возможно, если поле tb_uid не проиндексировано. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 11:13 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Кстати, нафига семь параметров биндить поодиночке как строковые? Возвращаемых то значений нет. Можно массивом в execute() передать. Другой вопрос, все ли передаваемые в запрос параметры должны быть строковыми? Возможно, :uid и :gid, если это какие-то идентификаторы юзера/группы, есть числовые. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 11:20 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
HettСкорее всего затык на COUNT(*) Точно нет, там пока таблица пустая, да и с единственным уникальным столбцом. Отрубил выборку оттуда – результат тот же. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 11:33 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkleДругой вопрос, все ли передаваемые в запрос параметры должны быть строковыми? Возможно, :uid и :gid, если это какие-то идентификаторы юзера/группы, есть числовые. :uid и :gid строки, :uid первичный и уникальный. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 11:37 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkleHettСкорее всего затык на COUNT(*)Возможно, если поле tb_uid не проиндексировано. в innodb индекс не поможет, движок все таки версионный ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 12:01 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatesting:uid и :gid строки, :uid первичный и уникальный.Эх, строки всяко дольше/сложнее сравнивать, а это непременно произойдет при проверке по уникальному индексу. В этом смысле числа существенно выигрывают. Ну и сам движок InnoDB не слишком быстрый в ряде случаев. Не пробовали таблицу конвернуть в MyISAM? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 12:24 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Hettв innodb индекс не поможет, движок все таки версионныйЭммм... Не вполне понимаю, что Вы имеете в виду. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 12:29 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkleНе пробовали таблицу конвернуть в MyISAM? Пробовал. Если что, на данный момент таблица крохотная, ~100 записей, т.е. тормоза вряд ли вызваны сравнением. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 12:46 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
коннект долгий? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 13:12 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatestingна данный момент таблица крохотная, ~100 записейНу это совсем ни о чем. Есть смысл построить временной профиль выполнения скрипта с целью поискать долгое место. http://php.net/manual/ru/function.microtime.php поможет. Ну и ещё момент.gpbetatestingВ боевом режиме функция может дёргаться примерно 50 раз в секундуНадо полагать, функция вызывается из единожды запущенного скрипта. Если так, то какой смысл 50 раз в секунду коннектиться к серверу (а это штука накладная, даже на локалхосте) и подготавливать запрос prepare()? Это можно сделать один раз за пределами функции. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 13:31 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkleНадо полагать, функция вызывается из единожды запущенного скрипта. Если так, то какой смысл 50 раз в секунду коннектиться к серверу (а это штука накладная, даже на локалхосте) и подготавливать запрос prepare()? Это можно сделать один раз за пределами функции. Вот здесь был бы очень благодарен за просвещение, как именно можно реализовать подобное. По сути дела да, сейчас схема такая: дёргается скрипт -> выполняется коннект -> выполняется функция. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 13:39 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatesting, Про коннект прогнал, он же и так за пределами функции. Ну туда же и prepare() просится. Внутрь функции $stmt передать по ссылке или через global, $dbh тоже. Не вполне понимаю смысл передачи подобных ресурсов по значению. gpbetatestingПо сути дела да, сейчас схема такая: дёргается скрипт -> выполняется коннект -> выполняется функция.Только я не понял теперь, действительно ли весь скрипт вместе с коннектом вызывается 50 раз в секунду (о, тут веселый шанс впереться в лимит на кол-во коннектов у мускуля!), или, всё же, скрипт запущен единожды и из него на одном коннекте 50 раз в секунду вызывается функция добавления строки. Например, в цикле. gpbetatestingвсе данные приходят от разных пользователейЭммм... Это веб-страничка регистрации пользователя на каком-то сайте или что? Ещё момент. Агрегатную функцию из запроса "SELECT COUNT(*) from `banned`..." вполне можно убрать. Думаю, вполне достаточно что-то вроде "SELECT 1 FROM `banned` WHERE `tb_uid` = '$uuid' LIMIT 1". А в результате смотреть, вернулась ли одна запись или ноль записей. При таком раскладе поиск в таблице прекращается после первой найденной записи, в то время как для COUNT() требуется найти все записи (даже если их всего одна) и потом посчитать количество не-NULL-евых значений (впрочем, для варианта с COUNT(*) есть какая-то внутренняя оптимизация). Для таблицы из сотни строк на глазок не будет заметно, конечно, но сделайте миллион записей с повторяющимися значениями... ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 14:35 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkleТолько я не понял теперь, действительно ли весь скрипт вместе с коннектом вызывается 50 раз в секунду (о, тут веселый шанс впереться в лимит на кол-во коннектов у мускуля!), или, всё же, скрипт запущен единожды и из него на одном коннекте 50 раз в секунду вызывается функция добавления строки. Например, в цикле. Первый случай, вкупе с "PDO::ATTR_PERSISTENT, true" и заранее увеличенным лимитом подключений. vkleЭммм... Это веб-страничка регистрации пользователя на каком-то сайте или что? Похожий принцип, отправка данных с созданием новой записи, если её ещё нет для данного пользователя, или с обновлением существующей. Насчёт добавления в цикле, как быть, если мы хотим отправить клиенту результат добавления именно его записи? Ведь там в конце функции идёт echo для этого. А цикл, насколько я понимаю, будет добавлять их "пачками". Про SELECT COUNT(*) учту, спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 14:48 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatestingА цикл, насколько я понимаю, будет добавлять их "пачками".Цикл это будет делать на одном ресурсе коннекта, а не на полусотне вновь создаваемых. Ибо, ресурс, ссылка на который хранится в переменной $dbh, не манна небесная, с неба не падает. Экземпляр класса PDO с соответствующим драйвером создается с нуля при каждом запуске скрипта. Это затратно, несмотря на атрибут "постоянный". Временной профиль выполнения скрипта сделали? Определили, сколько микросекунд занимает коннект, сколько селект и сколько инсерт/апдейт? Из того, что Вы сказали ранее о почти пустых таблицах, проблема видится только в долгом коннекте. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 15:27 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Еще можно в 2 раза меньше дергать MySQL server. Вместо 2-х prepare() и execute() использовать только query() заранее подготовив строку запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 15:36 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Посмотрел время создания коннекта через Код: php 1. 2. 3. 4. 5. 6.
В функции вставки в случае успеха клиенту приходил ответ с $contime. Число не выходит за пределы 0.0001-0.0002 секунд. Кроме того, ответ приходит моментально, а вот в phpmyadmin видно, что записи добавляются медленно, но в логах их скорость тоже почему-то высокая. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 16:36 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Сама же вставка вместе с подготовкой во время аналогичной проверки выдавала 0.0003-0.0005с, редко были числа порядка 0.01 ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 16:42 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatestingСама же вставка вместе с подготовкой во время аналогичной проверки выдавала 0.0003-0.0005с, редко были числа порядка 0.01Ага, другими словами, этот фрагмент скрипта легко может лететь аж до тысячи вставок в секунду, а то и быстрее. Очевидно, проблема не в этом месте. Как ведут себя остальные этапы, сколько времени вообще выполняется скрипт от первой до последней строчки? Справедливости ради замечу, что это будет время _выполнения_ скрипта, в которое не входит, например, его разбор и проверка синтаксиса интерпретатором PHP при запуске. gpbetatestingа вот в phpmyadmin видно, что записи добавляются медленноВизуально медленно или по выводимому времени? Визуально медленно вполне объяснимо, это же довольно монструозное приложение с кучей всяких файлов и скриптов. Пока всё отработает, загрузится, да браузер пошевелится... Ну а если по выводимому времени судить, то сколько численно показывает? И да, Вы знаете алгоритм вычисления времени в phpMyAdmin, знаете, что именно означает это число и в каких условиях оно получено? Вот я не знаю, а значит, и не могу судить о том, насколько хорошо или плохо работает запрос. ;-) Но могу сравнить с чем-то аналогичным. А ещё можно выполнить запрос в консольном клиенте mysql, он тоже время показывает. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 17:20 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkle, Весь скрипт выполняется в среднем за 0.0006с. Сейчас попробовал отправить 100 запросов со скоростью 60 в секунду и параллельно дёргать функцию, показывающую число записей в таблице – все отправленные записи добавились только через 30 секунд. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 17:46 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatestingпараллельно дёргать функцию, показывающую число записей в таблицеСмотрите реальное число записей функцией COUNT() или из статистики дергаете? Статистика на InnoDB и дольше тормозить умеет. А вот если реальное... это странно вообще. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 17:55 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
vkle, Через COUNT() ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 17:57 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
gpbetatesting, Ну это уж явно не PHP-шная проблема. А можете пояснить попобробнее вот этот момент?gpbetatestingдобавление 7500 записей закончится только через неприличные 25 минутПри 50 запросов/сек это получается 150 секунд или 2,5 минуты на все вставки от начала и до окончания. Вот прогнали Вы эти 7500 запросов за 2,5 минуты. А в таблице новые записи одна за другой неспешно стали появляться в последующие 22,5 минуты, или как? Сперва то, прочитав Ваш пост, я понял его так, что следующая вставка начинается после окончания предыдущей, что весь скрипт выполняется слишком долго, образуется очередь... Но теперь, спустя пол-дня, удалось понять, что скрипт работает быстро, и проблема в чем-то в другом. Но сама проблема стала менее понятной. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 18:22 |
|
PHP+MySQL: тормозит добавление записи в таблицу
|
|||
---|---|---|---|
#18+
Ещё момент: проверил – стоял маленький innodb_buffer_pool_size (128M при оперативке сервера в 4G). Поставил 3G, но это никак не повлияло на скорость Была мысль, что там занимается весь пул, и свежие запросы ждут, пока старые его освободят. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2018, 18:23 |
|
|
start [/forum/topic.php?fid=23&msg=39718200&tid=1460104]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
48ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 315ms |
total: | 465ms |
0 / 0 |