Замедляют ли пробелы в первичном ключе запросы? - PullRequest
2 голосов
/ 22 марта 2019

У меня есть таблица MySQL, где id - это первичный ключ с автоматическим приращением.

Поскольку у меня есть задание cron, которое запускается раз в минуту (обновление статистики из внешнего API) с использованием ON DUPLICATE KEY, я нахожу много пробелов в столбце id. У меня есть один столбец, который должен быть уникальным, очевидно, именно это и вызывает пробелы.

Например, есть только 183 строки, но я уже на 71511 для столбца id.

Единственный запрос SELECT, который я выполняю, похож на этот:

SELECT * FROM table WHERE member = '123' ORDER BY id DESC LIMIT 30

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

Например, если бы у меня была таблица с 100 000 строк, но id равен миллиарду, пробелы заставили бы вставки или выборки работать медленнее?

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

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

Независимо от того, равно ли значение вашего auto_increment 1 или755131 не имеет значения для повышения производительности.

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

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

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

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

Этоподход гарантирует:

  1. производительность - не нужно беспокоиться о том, каким должно быть состояние счетчика (должно ли оно уменьшаться или нет)

  2. уникальность - это самый быстрый и безопасный способ вычисления уникального идентификатора для строки - просто увеличьте число на auto_increment_offset.Не нужно беспокоиться о столкновениях, а что нет.Вы на 100% уверены, что если вы увеличите последнее число на auto_increment_offset - вы получите новый, уникальный и неиспользуемый номер в вашей базе данных /

С базами данных, особенно с MySQL- Существуют различные факторы, когда речь идет о производительности записи или чтения.Мин-макс и попытка возиться с auto_increment - не из тех.Все будет хорошо, если вы оставите все как есть.

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

1 голос
/ 22 марта 2019

Обычно я бы сказал, что это не проблема.Однако, это бросается в глаза:

Например, есть только 183 строки, но я уже на 71511 для столбца id.

Это много пробелов.Обычными причинами пробелов являются удаления и неудачные вставки (и в других базах данных распределение блоков идентификаторов для эффективности).

Кажется, вы понимаете пробелы.Вы можете устранить их, слегка касаясь вставок:

insert into t ( . . . )
    select . . .  --values here
    from dual
    where not exists (select 1 from t t2 where . . .)  -- duplicate key catch here
    on duplicate key . . .;

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

Необходимость использовать bigint для таблицы с 100 000 строк - это более чем нелегко.Большие целые числа удваивают размер индексов.Они увеличивают объем памяти, необходимый для записи на каждой странице.Увеличение размера базы данных увеличивает издержки ввода-вывода.

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