Войти в файл через PHP или войти в базу данных MySQL - что быстрее? - PullRequest
11 голосов
/ 08 октября 2008

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

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

Как бы вы вошли, что вы думаете, быстрее:

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

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

Ответы [ 15 ]

17 голосов
/ 08 октября 2008
  1. Запись в файл. Вращать журналы.

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

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

7 голосов
/ 08 октября 2008

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

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

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

6 голосов
/ 08 октября 2008

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

4 голосов
/ 08 октября 2008

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

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

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

Обновление: я провел быстрый тест - и, конечно же, если вам нужно открыть и закрыть файл, он примерно с той же скоростью или медленнее, используя тест из 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");
2 голосов
/ 08 октября 2008

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

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

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

INSERT DELAYED INTO `hits` ...

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

2 голосов
/ 08 октября 2008

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

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

2 голосов
/ 08 октября 2008

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

2 голосов
/ 08 октября 2008

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

1 голос
/ 08 октября 2008

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

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

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

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

1 голос
/ 08 октября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...