Существует ли эффективный и надежный способ определения времени последнего обновления для коллекции таблиц в mysql? - PullRequest
0 голосов
/ 30 марта 2020

Classi c проблема: у меня есть много клиентских приложений (нативных и веб-приложений), подключенных к системе, и все они должны получать обновления в режиме реального времени при изменении информации. Большая часть информации меняется редко. Когда это происходит, клиентские системы должны знать это очень быстро. Бэкэнд-система использует MariaDB в кластере Galera с InnoDB в качестве механизма хранения.

Мне известно, что вы можете использовать INFORMATION_SCHEMA для такого рода проблем, но это недетерминировано c при использовании таблиц INNODB - особенно в кластерной среде Galera. возможно , что если я буду полагаться на UPDATE_TIME рассматриваемых таблиц, он будет немного устаревшим из-за буферизации в памяти. Также возможно, что разные серверы в кластере будут иметь разные значения для этого времени в любой данный момент. Это большое дело? Я сомневаюсь в этом. Но я искал решение, которое дало бы мне точные данные и было бы производительным.

В каждой рассматриваемой таблице есть столбец updated_at с индексом. Я пробовал запрашивать каждую таблицу отдельно (например, select updated_at from TABLE order by updated_at limit 1), но это очень дорого, когда нужно проверить много таблиц. Хранимая процедура делает это несколько более эффективным, но все равно кажется, что оно не элегантное.

Например, могут ли триггеры иметь здесь смысл? Таблицы обновляются относительно редко по сравнению с операциями чтения таблиц. Могу ли я установить триггер вставки / удаления / обновления для каждой таблицы, которая обновила соответствующее время last_updated в ДРУГОЙ таблице? Затем просто проследите за этой таблицей, чтобы решить, изменились ли данные, которые меня беспокоили Должен ли я использовать какой-нибудь паб / подпункт, чтобы сигнализировать «вне диапазона» об изменении данных? Тогда есть вещи, которые заботятся, подписаться на это?

Это должно быть решенной проблемой. Кто-нибудь может предложить отличное решение?

1 Ответ

0 голосов
/ 30 марта 2020

Вы можете запросить метаданные следующим образом:

SELECT MAX(UPDATE_TIME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'myschema'

Но вы сказали, что метаданные не достаточно точны для вас.

Вы должны получить последнюю updated_at от несколько таблиц:

SELECT MAX(updated_at) AS max_updated_at
FROM (
    SELECT MAX(updated_at) AS updated_at FROM mytable1
    UNION SELECT MAX(updated_at) FROM mytable2
    UNION SELECT MAX(updated_at) FROM mytable3
    UNION SELECT MAX(updated_at) FROM mytable4
    UNION ...
) AS t

Или в качестве альтернативы:

SELECT GREATEST(
    t1.updated_at,
    t2.updated_at,
    t3.updated_at,
    t4.updated_at,
    ...
  ) AS max_updated_at
FROM
(SELECT MAX(updated_at) AS updated_at FROM mytable1) AS t1, 
(SELECT MAX(updated_at) AS updated_at FROM mytable2) AS t2,
(SELECT MAX(updated_at) AS updated_at FROM mytable3) AS t3,
(SELECT MAX(updated_at) AS updated_at FROM mytable4) AS t4,
... 

Ваш комментарий:

Извинения за неправильное толкование вашего вопроса. Я предположил, что «время последнего обновления для коллекции таблиц» означает время последнего обновления для collection .

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

SELECT TABLE_NAME, UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'myschema'

Или:

SELECT 'mytable1' AS table_name, updated_at FROM mytable1
UNION SELECT 'mytable2', updated_at FROM mytable2
UNION SELECT 'mytable2', updated_at FROM mytable3
UNION SELECT 'mytable2', updated_at FROM mytable4
UNION ...

Или:

SELECT 
    t1.updated_at AS mytable1_updated_at,
    t2.updated_at AS mytable2_updated_at,
    t3.updated_at AS mytable3_updated_at,
    t4.updated_at AS mytable4_updated_at,
    ...
FROM
(SELECT MAX(updated_at) AS updated_at FROM mytable1) AS t1, 
(SELECT MAX(updated_at) AS updated_at FROM mytable2) AS t2,
(SELECT MAX(updated_at) AS updated_at FROM mytable3) AS t3,
(SELECT MAX(updated_at) AS updated_at FROM mytable4) AS t4,
... 

Если столбец таблицы updated_at имеет index, MySQL может быстро получить значение MAX() из последней записи в индексе без необходимости сканирования всей таблицы.

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