Почему на хостинге запись всего лишь 1 значения (Timestamp) в БД MySQL работает быстрее, чем в файл, хотя у меня на компе быстрее файл?
Повторюсь: значение всего лишь 1. Это TIMESTAMP.
1 столбец, 1 строка.
Вариант с таблицей:
в БД MySQL есть таблица с одним столбцом и одной строкой, в ней некое значение.
В PHP делается UPDATE.
Замеряется производительность именно этого UPDATE.
Вариант с файлом:
file_put_contents("имя_файла", "значение");
То есть файл получается текстовый, весит он 10 байт.
На моем компе с файлом гораздо быстрее, что и логичнее, ведь в файле по большому счету ни одного лишнего байта не пишется, а в БД помимо самого значения пишутся и еще байты, это уже принцип БД.
Однако на хостинге (это hostinger.ru - НЕ реклама, хостинг не очень хорош) все иначе, вариант с БД занимает 1-2 мсек (собсна UPDATE-запрос), с файлом - до десятков-сотен мсек.
Вопросы:
1) Какие могут быть тому причины, КРОМЕ того, что БД у них лежит на другом хосте, который, по-видимому, быстрее (а у меня все на 1 компе)?
1.1) Если никаких, то, значит, вывод из моих наблюдений: сервак с MySQL у них быстрее?
2) Часто ли у хостеров БД на другом хосте? Часто ли быстрее?
3) Еще есть идея попробовать бинарный вариант (ИМХО ерунда - 6 байт погоды не делают), также попробовать fopen-fwrite-fclose (ИМХО быстрее относительно file_put_contents, но тоже немного)...
P.S.
Прошу прощения за корявый вопрос.
Просто я по глупости не ожидал подобного, уже многое сделал, теперь переделывать, что нервирует.
Вы рассматриваете вопрос записи данных на диск слишком узко.
Запись одного значения в файл не будет особо отличаться от записи одного значения в таблицу приведённую вами в пример. Да, субд имеют свой оверхед, но современные субд очень сильно оптимизированы и в данном случае разница значительной не будет.
Но, эту разницу могут делать значительной иные факторы... Например вы вызвали file_put_contents, которая обратилась к вашей ФС и сказала (образно говоря разумеется :) ) "запиши это вот сюда" и ФС ответила "ОК", file_put_contents вернула успех и пхп продолжил выполнение кода.
Только вот если ФС сказала "ОК" - это еще не означает, что данные были физически записаны на диск... Данные могут еще довольно существенное время (вплоть до сотен милисекунд) находится в кэше ФС и лишь после быть "сброшены" на диск. А вот современные субд, заботясь о целостности данных как правило после ответа фс "ОК" - отдают еще команду синхронизации, принудительно заставляя ФС скинуть данные на диск и только после этого, возвращают вам успешный ответ... От сюда, в пределах вашего примера, незначительная разница в скорости, с вашей точки зрения - может стать значительной...
Что касается вопроса про хостера, причин тоже может быть не мало... База может находится на SSD диске или RAID массиве (0 или 01 например)... Может быть разница в приоритете работы с диском (ionice) и прочие административные ограничения хостера, дабы клиент не "положил" сервак бешенным IO к диску.
Да, у хостеров БД часто на другом сервере находится. Таким образом оборудование чётко разделяется на зоны применения и каждая зона настраивается максимально под узкие задачи, что приводит к значительному упрощению администрирования и приличному росту производительности. А так же росту оверхеда если общение через TCP протокол.
> Только вот если ФС сказала "ОК" - это еще не означает, что данные были физически записаны на диск...
Хм...
Что-то вот не могу я себе такого представить, чтобы какое-нибудь десктопное приложение записало файл, затем выполнение пошло дальше, а файла-то и нет.
1) Как такое может быть?
2) Почему тогда не бывает такого, что записываешь файл, следующей строчкой кода его же читаешь, а файла нет? Или же будучи в кэше, данные все равно читаются как будто бы из файла? Если да, то чем собственно плох кеш?
3) А если file_put_contents заменить на более низкоуровневые fopen-fwrite-fclose?
> отдают еще команду синхронизации
Где почитать об этой синхронизации?
VZVZ: Когда приложение запрашивает у ФС какой либо элемент, ФС сначала смотрит в свой кэш, а потом, если нужный кэш отсутствует(или текущий устарел), читает с диска и прочитанное так же ложит в кэш. Этот механизм необходим чтобы снизить износ диска когда идет частое обращение к "горячим" данными. Поэтому даже записанное в кэш становится доступно для всех приложений моментально.
Проблема кэша в том, что если между записью в кеш и "сбросом" на диск произойдёт, например, отключение электроэнергии - данные будут потеряны. Вероятность этого весьма мала, т.к. сброс на диск в современных ФС происходит в короткий промежуток времени - от 50 до 500мс в зависимости от настроек, но все равно такая ситуация реальна.
Когда нужен факт физической записи на диск нужно использовать принудительную синхронизацию с диском, но к сожалению в стандартной поставке php не обладает таким функционалом, поэтому использование более низкоуровневых функций не поможет (в них попросту нет вызова fsync). Такой функционал можно добавить только через расширения, например Eio (функция eio_fsync), но это расширение не присутствует в стандартном наборе и потому отсутствует у большинства хостеров.
Почитать о синхронизации ФС можете загуглив фразу fsync - это название стандартной сишной функции из библиотеки libc, которая есть в каждом дистрибутиве linux (в винде может называться чуток по другому). Если нет проблем с английским - вот неплохая статья https://en.wikipedia.org/wiki/Sync_(Unix)
VZVZ: Соответственно про синхронизацию в базах данных запрос нужно дополнить названием базы :) Но как правило в современных субд синхронизация включена всегда, это требование ACID.
Виталий: спасибо вам и на том! Придется гуглить, читать, все как обычно.
А fsync - это чисто линуксячья фича, или на винде тоже что-то такое есть?
Пока вижу, что вопрос "БД vs файл" действительно не так прост даже в таком простейшем случае, как мне казалось.
Компа с линуксом я не имею.
Видимо, пока лучше тупо потестить реальные хостинги, а не локалхсот, и сделать выводы.
VZVZ: Конкретно fsync (само название функции) это функция библиотеки libc , а основным "потребителем" этой библиотеки является линукс (а еще андроид и некоторые другие мобильные ОС на базе линукса). Но эту библиотеку можно использовать и на других системах, включая винду.
В целом функции синхронизации обязательно есть во всех современных ОС и языковых библиотеках (libc стандартная библиотека языка Си, для винды и C# это вероятно Microsoft C Run-time Library). В винде такая функция тоже есть, но т.к. я специализируюсь именно на линукс-юникс системах, я не знаю как она там называется.
Низкоуровневые оптимизации - тема очень обширная, вам стоит проанализировать вашу задачу и расставить приоритеты в ней. Тут как нигде актуальна дилемма 90\10 - на первые 90% задачи тратится 10% времени, но на оставшиеся 10% задачи - уходит до 90% всего времени... Если вы задаётесь этим вопросом исходя из повышения собственной квалификации - то это очень хорошо, но если вы решаете конкретную задачу, залезая в эти дебри вы рискуете потратить тонну времени, получив в итоге минимальную выгоду.
открою вам небольшую тайну, если вам нужна супер скорость и вы храните такие простые данные - используйте просто redis (или даже memcache на худой конец).
зачем сравнивать файлы vs mysql если вас не устраивает их скорость?
Все нормально. База отрабатывает быстрее и в порядке приоритетов. Запись на диск, да еще через php в данном случае куда меньший. И они правы, что так настроили.
При этом можно предположить похожее:
Соединение с базой всегда открыто, к примеру через сокет, база также держит открытым дескриптор файла с данными.
А вам нужно получить дескриптор, сделать запись, закрыть файл. Уже куда дольше.