Как правильно выбрать вновь добавленные строки в таблице? - PullRequest
1 голос
/ 02 января 2011

Мне нужно периодически обновлять локальный кеш с новыми дополнениями к некоторой таблице БД.Строки таблицы содержат поле с автоинкрементом порядковый номер (SN).Кэш также хранит это число, поэтому в основном мне просто нужно извлечь все строки с SN больше, чем у меня уже есть самое высокое.

SELECT * FROM table where SN > <max_cached_SN>

Однако большинство попыток не принесут данных (мне просто нужно убедиться, что у меня есть абсолютно актуальная локальная копия).Так что я хотел бы узнать, будет ли это более эффективным:

count = SELECT count(*) from table;
if (count > <cache_size>)
  // fetch new rows as above

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

Ответы [ 5 ]

3 голосов
/ 02 января 2011

этот тест / обновление будет выполняться довольно часто, и многие клиенты

могут привести к неожиданной гонке за генерацию кэша

Я бы предложил

  • при новом добавлении в вашу таблицу добавить новейший идентификатор в таблицу очередей
  • , используя аналогичный crontab для запуска генерации кеша путем проверки таблицы очереди
  • после создания нового кэша удалите идентификатор из таблицы очередей

, так как вы подчеркиваете , большинство попыток не принесут данных , приведенное выше сработает только при наличии нового добавления

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

2 голосов
/ 02 января 2011

Я верю, что

SELECT * FROM table where SN > <max_cached_SN>

будет быстрее, потому что выбор счетчика (*) может вызвать сканирование таблицы. Просто для пояснения, вы никогда не удаляете строки из этой таблицы?

1 голос
/ 02 января 2011

Вам не нужно использовать SELECT COUNT(*)

Существует два решения.

  1. Вы можете использовать temp table с one field, которые содержатlast count of your table и создайте новое Trigger после вставки в свою таблицу и поле таблицы временного хранения в Trigger.

  2. Можно использовать temp table, в котором есть одно поле, содержащее last SN вашей таблицы кэшируется и создается новый Trigger после вставки в таблицу и обновления поля временной таблицы в Trigger.

1 голос
/ 02 января 2011

SELECT COUNT(*) может включать сканирование (даже полное сканирование), в то время как SELECT ... WHERE SN > constant может эффективно использовать индекс по SN, и может быть достаточно просмотра очень небольшого числа узлов индекса.Не считайте предметы, если вам не нужна точная сумма, это дорого.

0 голосов
/ 02 января 2011

не так много на самом деле

drop table if exists foo;
create table foo
(
foo_id int unsigned not null auto_increment primary key
)
engine=innodb;

insert into foo values (null),(null),(null),(null),(null),(null),(null),(null),(null);

select * from foo order by foo_id desc limit 10;

insert into foo values (null),(null),(null),(null),(null),(null),(null),(null),(null);

select * from foo order by foo_id desc limit 10;
...