2010-09-08 2 views
7

Мое приложение должно опросить базу данных MySQL для новых строк. Каждый раз, когда новые строки добавляются, их следует извлекать. Я думал создать триггер для размещения ссылок на новые строки в отдельной таблице. Исходная таблица имеет более 300 000 строк.Каков самый быстрый способ опроса таблицы MySQL для новых строк?

Приложение построено на PHP.

Некоторые хорошие ответы, я думаю, что вопрос заслуживает щедрости.

+2

IMO, если возможно, любой слой, который вы используете для вставки, то есть услуги, обертывающие операции CRUD, должны «уведомлять» ваше приложение после вставки. Таким образом, вы не постоянно проводите опрос. – Alex

+0

@Alex: Это два разных независимых приложения. Второе приложение читает только из базы данных. – HyderA

+1

Я бы сказал, что триггер AFTER INSERT будет на месте, реализован на уровне MySQL и позволит скриптам опросить и очистить новые записи в другой таблице. Таким образом, даже форсирование еще одного (не автоинкрементного) id будет работать. – Wrikken

ответ

7

Для внешних приложений, которые я нахожу с использованием колонки TimeStamp является более надежным методом, который не зависит от автоматической идентификации и других первичных ключевых вопросов

Добавление столбцов в таблицах, таких как:

insertedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP 

или для отслеживания вставки и обновление

updatedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 

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

+0

Индексирование такого поля всегда будет полезным, причем не только в случае больших таблиц. +1 в любом случае. –

+0

Индексирование обычно полезно. Существует много вариантов использования, когда накладные расходы индекса не стоят. Обычно таблица, в которой есть много вставок и удалений между каждым выбором на основе TIMESTAMP и выбором на основе TIMESTAMP, выполняется нечасто – TFD

+1

Что-то, с чем следует обращаться с этим решением: если приложение, выполняющее опрос, получает изменения в партиях (например, 'SELECT * FROM TABLE WHERE updatedOn>: LAST_TIMESTAMP ORDER BY updateOn LIMIT 100'), и есть возможность больше, чем размер партии может быть обновлен сразу (например, 'UPDATE TABLE SET COLUMN = 'VALUE' WHERE OTHER_COLUMN = 'ЧТО-ТО, ЧТОБЫ ВЫБРАТЬ СОТНИ ROWS''), то вы пропустите строки. – ICR

3

Вы можете использовать следующую инструкцию, чтобы выяснить, если новая запись была вставлена ​​в таблице:

select max(id) from table_name 

заменив имя первичного ключа и имени таблицы в отчете выше. Храните значение max (id) во временной переменной и извлекайте все новые записи между этим и последним сохраненным значением max (id). После извлечения новых записей установите максимальное (id) значение в том, которое вы получили от запроса.

+1

Почему бы не выбрать * from table_name, где id>: max –

0

Предполагая, что у вас есть идентификатор или некоторые другие данные, которые всегда растут, вы должны отслеживать свое приложение php из последнего найденного идентификатора.

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

0

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

<? 
$idFile = 'lastID.dat'; 

if(is_file($idFile)){ 
    $lastSelectedId = (int)file_get_contents($idFile); 
} else { 
    $lastSelectedId = 0; 
} 

$res = mysql_query("select * from table_name where id > {$lastSelectedId}"); 

while($row = mysql_fetch_assoc($res)){ 
    // Do something with the new rows 

    if($row['id']>$lastSelectedId){ 
     $lastSelectedId = $row['id']; 
    } 
} 

file_put_contents($idFile,$lastSelectedId); 

?> 
0

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

Ваше приложение, запрашивающее таблицу (или файл) одной строки, чтобы увидеть, изменилась ли временная метка из локального хранилища, не должно быть большим количеством ударов по производительности. Затем выборка новых строк из таблицы строк 300k на основе метки времени должна быть в порядке, предполагая, что временная метка правильно проиндексирована.

Однако, прочитав ваш вопрос, мне было любопытно, могут ли триггеры Mysql выполнять системные вызовы, скажем, сценарий php, который будет делать тяжелый подъем. Выводит they can с помощью sys_exec()User-Defined Function. Вы можете использовать это, чтобы делать все виды обработки, передавая им вставленные данные строки, по существу имея мгновенное уведомление о вставках.

И наконец, a word of caution об использовании триггеров для вызова внешних приложений.

0

Одним из вариантов может быть использование инструкции INSERT INTO SELECT. Забрав из предложений, используя временные метки, чтобы тянуть последние строки, вы могли бы сделать что-то вроде ...

INSERT INTO t2 (
    SELECT * 
    FROM t1 
    WHERE createdts > DATE_SUB(NOW(), INTERVAL 1 HOUR) 
); 

Это займет бы все строки, вставленных в предыдущем часе и вставить их в таблицу 2. Вы можете иметь сценарий запускает этот запрос и запускает его каждый час (или любой необходимый вам интервал).

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

Решение Fanis также звучит так, как будто оно может быть интересным.

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

INSERT INTO t2 (field1, field2) (
    SELECT field1, field2 
    FROM t1 
    WHERE createdts > DATE_SUB(NOW(), INTERVAL 1 HOUR) 
); 
1

Создание PHP Daemon контролировать размер MySQL Таблица файла, если размер изменяет запрос для новых записей, если новый найденные записи запускают следующий процесс.

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

+1

Я не уверен в MySQL, но обычно табличное пространство выделяется кусками, так что, как только выделение будет выполнено, несколько строк могут быть добавлены до того, как возникнет необходимость в другом распределении. – pascal

+0

Многие таблицы находятся в одном файле при использовании innodb. – frodeborli

Смежные вопросы