Войти в файл через PHP или войти в базу данных MySQL - что быстрее?

У меня есть веб-сайт на основе базы данных, обслуживающий около 50 000 страниц.

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

Как бы вы регистрировались, что, по вашему мнению, быстрее:

a) Используйте PHP для добавления в конец текстового файла журнала.

б) Используйте MySQL, чтобы ВСТАВИТЬ В неиндексированную таблицу журнала.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
11
0
13 785
15

Ответы 15

Я считаю, что в плоский файл будет быстрее писать.

В файл будет быстрее, но в БД будет лучше.

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

Если у вас открыта база данных, я думаю, что, вероятно, будет быстрее вставить одну строку.

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

Обновление: я провел быстрый тест - и, конечно же, если вам нужно открывать и закрывать файл, он примерно такой же или медленнее, используя тест из 10000 строк:

Однако, когда у вас начинает работать несколько процессов, это замедляется, как показано ниже. Это с 10 параллельными процессами (все время в секундах)

DB time: 2.1695
DB time: 2.3869
DB time: 2.4305
DB time: 2.5864
DB time: 2.7465
DB time: 3.0182
DB time: 3.1451
DB time: 3.3298
DB time: 3.4483
DB time: 3.7812
File open time: 0.1538
File open time: 0.5478
File open time: 0.7252
File open time: 3.0453
File open time: 4.2661
File open time: 4.4247
File open time: 4.5484
File open time: 4.6319
File open time: 4.6501
File open time: 4.6646
Open close file time: 11.3647
Open close file time: 12.2849
Open close file time: 18.4093
Open close file time: 18.4202
Open close file time: 21.2621
Open close file time: 22.7267
Open close file time: 23.4597
Open close file time: 25.6293
Open close file time: 26.1119
Open close file time: 29.1471

function debug($d)
{
    static $start_time = NULL;
    static $start_code_line = 0;

    if ( $start_time === NULL )
    {
        $start_time = time() + microtime();
        $start_code_line = $code_line;
        return 0;
    }

    printf("$d time: %.4f\n", (time() + microtime() - $start_time));
    $fp = @fopen('dbg.txt','a');
    fprintf($fp,"$d time: %.4f\n", (time() + microtime() - $start_time));
    fclose($fp);

    $start_time = time() + microtime();
    $start_code_line = $code_line;
}

function tfile()
{
    $fp = @fopen('t1.txt','a');
    for ($i=0;$i<10000;$i++)
    {
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        fwrite($fp,$txt);
    }
    fclose($fp);
}
function tfile_openclose()
{
    for ($i=0;$i<10000;$i++)
    {
        $fp = @fopen('t1.txt','a');
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        fwrite($fp,$txt);
        fclose($fp);
    }
}

function tdb()
{
    $db = mysql_connect('localhost','tremweb','zzxxcc');

    $select_db = mysql_select_db('scratch');

    if (!$select_db) 
        die('Error selecting database.');

    for ($i=0;$i<10000;$i++)
    {
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        mysql_query("INSERT INTO tlog values('".$txt."')");
    }
}

debug("");

tfile();
debug("File open");

tfile_openclose();
debug("Open close file");

tdb();
debug("DB");

Вот почему разные процессы должны записывать в разные файлы ... Агрегировать позже. Все, что вам нужно беспокоиться об открытии / закрытии, - это буферизация журналов при ротации файлов с интервалами записи в журнал (один раз в час, вероятно, подходит для такого рода нагрузки).

SquareCog 08.10.2008 21:47

Действительно - однако я бы вообще не стал писать в файл журнала. Как только вы начнете делать такие вещи, как агрегирование и ротация, это становится своего рода процессом, который пойдет не так, как в первом случае, и с небольшой выгодой с точки зрения ЦП. Базы данных хороши для хранения и извлечения данных ....

Richard Harrison 08.10.2008 22:49

OP здесь, мне это кажется убедительным в сочетании с отложенной вставкой

Alan 09.10.2008 00:07

Я бы порекомендовал вам протестировать оба варианта с помощью нескольких тестовых примеров.

Я бы предположил, что плоский файл будет быстрее, b / c это действительно то, что делает БД - она ​​просто записывает его в файл. Единственное преимущество, о котором я могу думать, заключается в том, что если база данных может работать одновременно, вы можете получить лучшие результаты.

Я бы использовал отложенную вставку в MySQL. Таким образом, вам не придется ждать окончания вставки.

Интересно, что я не слышал об этих отложенных вставках, они кажутся идеальными для регистрации.

Alan 08.10.2008 21:41

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

SquareCog 08.10.2008 21:45

Это правда, что он не узнает, если вставка выйдет из строя. Но если журналы предназначены только для статистики по просмотру страниц, и у него уже есть соединение с базой данных, отложенная вставка должна быть хорошей. Если журналы для него критичны, то это не лучшее решение.

Eric Hogue 08.10.2008 22:28

OP здесь, да, в моем случае это не важно, если INSERT не работает.

Alan 09.10.2008 00:04

Честно говоря, тогда это хорошее решение для вас, особенно из-за простоты реализации. Вы теряете некоторую гибкость и надежность, но при этом значительно экономите время и сложность разработки. Проголосовали! :-)

SquareCog 09.10.2008 03:11

Теперь это устарело! dev.mysql.com/doc/refman/5.6/en/insert-delayed.html

ϹοδεMεδιϲ 06.09.2012 14:28

Все зависит от вашей инфраструктуры и ограничений. Если диск медленный, запись будет медленной. Если SQL-сервер отстает от запросов, вставка будет медленной. Плоский файл, вероятно, лучший вариант, но я бы написал ваш код или использовал существующий код (PEAR :: Log), чтобы вы могли изменить поставщика и метод хранения по своему желанию.

Вы можете попробовать оба способа, используя log4php, который поддерживает:

  • Конфигурация через xml и файл свойств (та же структура, что и log4j).
  • Файл, RollingFile, DailyFile, Echo, Console, Mail, PEAR :: Db, ошибка PHP, события Syslog или NT и приложения для сокетов.
  • Простые, TTCC, Pattern, HTML и Xml макеты.
  • Вложенные (NDC) и сопоставленные (MDC) диагностические контексты.
  • Переключаемая внутренняя отладка.

Что касается входа в файл, вы можете повысить производительность за счет буферизации запросов на запись.

  1. Записать в файл. Поверните журналы.

  2. Пакетная загрузка файла в базу данных по расписанию.

Есть много, много причин выбрать эту архитектуру - простота масштабирования (запись во многие журналы, загрузка их в базу данных), отсутствие зависимости от SPOF в базе данных (если что-то пойдет не так, вы просто накапливаете журналы на некоторое время) , возможность выполнять очистку и нетривиальный синтаксический анализ во время загрузки, не перегружая рабочие серверы, и многое другое.

Несколько соображений:

  1. Вы думаете, что захотите объединить данные журнала с другими данными в базе данных? Если это так, накладные расходы на вставку db, вероятно, оправданы, поэтому существующие отношения можно легко использовать.
  2. Позволит ли регистрация данных в базе данных значительно уменьшить объем регистрируемых данных (из-за существующих отношений в базе данных)? Например, журнал активности пользователей в базе данных может быть просто таблицей, содержащей идентификатор пользователя, идентификатор активности и временную метку. Файл журнала, подобранный в виде файла, не будет читаться человеком. В зависимости от ваших потребностей вам нужно будет записать хотя бы часть данных пользователя в файл журнала, чтобы убедиться, что он может быть полезен и удобочитаем сам по себе.
  3. Есть ли шанс, что вы захотите использовать эти данные журнала во внешнем интерфейсе или с помощью инструмента администрирования в будущем? В таком случае запись в БД, вероятно, предпочтительнее.

Как уже упоминалось, это зависит от множества вещей, таких как трафик, скорость диска и т. д. Вам нужно будет протестировать оба сценария.

При тестировании MySQL попробуйте MyISAM и INNODB. Теоретически Innodb будет работать лучше, поскольку у него есть блокировка на уровне строк.

Я сделал нечто подобное. Я регистрирую каждую запись в отдельном файле, затем у меня есть пакетный процесс, который захватывает файлы, помещает их в файл tar и выгружает их на центральный сервер журналов (в моем случае S3 :)).

Я генерирую случайные имена файлов для каждой записи журнала. Я делаю это, чтобы файлы не блокировались при вращении. Таким способом очень легко заархивировать / удалить.

Я использую json в качестве формата журнала вместо обычных файлов журнала, разделенных пробелами. Это упрощает синтаксический анализ и добавление полей в будущем. Это также означает, что мне проще написать запись для каждого файла, чем добавлять несколько записей для каждого файла.

Я также использовал log4php + syslog-ng для централизации ведения журнала в реальном времени. У меня есть журнал log4php в системном журнале, который затем пересылается в журналы на мой центральный сервер. Это действительно полезно для больших кластеров. Одно предостережение заключается в том, что существует ограничение на длину сообщений системного журнала, поэтому вы рискуете усечь более длинные сообщения.

Если это для сайта, управляемого базой данных, почему бы вам просто не использовать встроенные возможности ведения журнала Apache или IIS и подходящий инструмент отчетности, такой как AWStats и другие, всегда есть Гугл Аналитика

Я предпочитаю вести журнал AWStats и веб-сервера - по сути, вы все равно получаете его бесплатно - даже если вы не анализируете трафик, вы все равно можете подумать о том, чтобы самостоятельно проанализировать файл журнала доступа Apache для любой пакетной обработки, которую вам нужно выполнить.

Вам следует попробовать SQLite. Это даст вам как скорость записи в файл, так и мощность базы данных.

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

Cruachan 08.10.2008 23:27

Много лет назад я прочитал статью в C++ Users Journal о производительности входа в систему. Независимо от того, используете ли вы базу данных или файлы, лучше всего записывать неформатированные данные, которые могут быть «преобразованы» в значимые данные, когда (и, что более вероятно, если) вам нужно просмотреть журналы. Подавляющая часть затрат на ведение журнала связана с информацией о строках, которые записываются в место назначения, и большую часть времени эти затраты тратятся зря - журналы никогда не читаются.

Я могу найти ссылку на статью, если она будет вам полезна.

Если вы используете ведение журнала на основе файлов или ведение журнала на основе базы данных, самым большим ударом по производительности будет блокировка файлов / таблиц. По сути, если клиент A и клиент B соединяются в течение относительно небольшого периода времени, клиент B зависает, ожидая снятия блокировки файла / таблицы совпадений, прежде чем продолжить.

Проблема с файловым механизмом заключается в том, что блокировка файлов необходима для предотвращения повреждения ваших обращений. Единственный способ обойти это - реализовать очередь для отложенной записи в файл.

С ведением журнала базы данных вы можете, по крайней мере, делать следующее [MySQL с использованием MyISAM]:

INSERT DELAYED INTO `hits` ...

См. 12.2.5.2. INSERT DELAYED синтаксис для получения дополнительной информации.

устарело сейчас, согласно MySQL v5.6

ϹοδεMεδιϲ 06.09.2012 14:29

Другие вопросы по теме