Лучший способ управлять истечением строки в mysql

Приложение выполняет следующие действия:

записывает строку в таблицу с уникальным идентификатором прочитайте таблицу и найдите уникальный идентификатор и выведите другие переменные (среди которых отметка времени).

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

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

Задача cron (запускать каждую минуту) (или расписание событий mysql) для этого может быть одной из следующих (или любой другой идеи?) на основе метки времени:

A) добавьте переменную BOL, чтобы индексировать таблицу, а затем читать WHERE не истек (в зависимости от переменной boll, конечно) B) добавьте переменную BOL, чтобы разбить таблицу, а затем прочитать только соответствующий раздел (я новичок в разделении, поэтому я не уверен, как это может получиться) C) прочитайте всю таблицу и удалите каждую строку, истекшую, а затем запишите одну и ту же строку в другую таблицу D) при записи записывайте две строки одновременно в двух таблицах, а затем удаляйте истекшие в одной таблице

ИЛИ

E) вообще не использовать задание cron и проверять метку времени при каждом чтении. (но зачем мне сканировать всю таблицу? Истекшая строка в основном бесполезна для самого приложения)

Изменить 1

Позвольте мне перефразировать вопрос:

Цель состоит в том, чтобы rietrieve все поля строки, только если строка была написана менее 2 минут назад:

Таблица имеет эту структуру, но может быть полностью переопределена

transactionID CHAR(8) NOT NULL, 
PRIMARY KEY(transactionID),
details VARCHAR(416),
tel INT(10),
time TIMESTAMP(),
address VARCHAR(60),
town VARCHAR(30),
flat VARCHAR (5),
supplier SMALLINT()

также supplier является внешним ключом

индексы transactionID и в конечном итоге "status", дополнительный столбец, тип данных TO_BE_DEFINED_but_probably_SMALLINT _?()

Решение 1: используйте индексированный столбец, который указывает статус строки (истек, активен, используется)

Достигнуто выполнение задания cron, чтобы изменить значение поля от 1 (активное) до 2 (истек) и запрос будет следующим:

$transaction = //a POST or GET 

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND status = 1");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

Решение 2: используйте раздел на основе метки времени каждой строки

Достигнуто выполнение задания cron, чтобы разбить столбец каждые 2 минуты, но тогда запрос, вероятно, будет быстрее:

$transaction = //a POST or GET 

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND PARTITION (active)");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

Тогда задание cron будет похоже на это

$date = date("Y-m-d H:i:s");
$time = strtotime($date);
$check = $time - (2);


$query = mysqli_query($con,"PARTITION BY RANGE (timestamp_field) 
(PARTITION active VALUES LESS THAN ($check)),
((PARTITION expired VALUES MORE THAN ($check));")

Решение 3: забудьте все это и скопируйте строки с меткой времени старше 2 минут в другую таблицу с заданием cron

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

Решение 3B: добавив строку, напишите ее также в другой таблице, чтобы она выполняла только функцию DELETE, выполняемую заданием cron.

Решение 4: забудьте об этом и ГДЕ на отметке времени

$transaction = //a POST or GET 

$date = date("Y-m-d H:i:s");
$time = strtotime($date);
$check = $time - (2);

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND timestamp > $check");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

Ответ 1

Вы не указали, какую версию MySQL вы используете. Пока у вас есть 5.1, у вас есть планировщик событий.

CREATE EVENT clearExpired
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
DO
   UPDATE table SET status=0
    WHERE status <> 0
      AND TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;

или

CREATE EVENT clearExpired
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
DO
   DELETE FROM table
    WHERE TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;

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

Для эффективности измерения создайте таблицу events (столбцы: временная метка и действие) и создайте огромное количество строк в таблице, а затем измените свое событие на:

...
DO
   BEGIN
      INSERT INTO events SET action="clearExpired start";
      <insert or delete>
      INSERT INTO events SET action="clearExpired end";
   END

Затем вы можете видеть, сколько времени занимает один путь против другого.

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