У меня есть таблица MySQL с 3 миллионами строк (listings
) на данный момент.Эти списки обновляются 24/7 (около 30 записей в секунду) скриптом Python (Scrapy
) с использованием pymsql
- поэтому производительность запросов актуальна!
Если listing
не делает 't существует (т. е. UNIQUE
url
), будет вставлена новая запись (примерно каждый сотый листинг).id
установлен на auto_increment
, и я использую INSERT INTO listings ... ON DUPLICATE KEY UPDATE last_seen_at = CURRENT_TIMESTAMP
.Обновление last_seen_at
необходимо для проверки того, что элемент все еще находится в сети, так как я сканирую страницу результатов поиска с несколькими списками на ней и не проверяю каждый отдельный URL каждый раз.
+--------------+-------------------+-----+----------------+
| Field | Type | Key | Extra |
+--------------+-------------------+-----+----------------+
| id | int(11) unsigned | PRI | auto_increment |
| url | varchar(255) | UNI | |
| ... | ... | | |
| last_seen_at | timestamp | | |
| ... | ... | | |
+--------------+-------------------+-----+----------------+
Проблема:
Сначала все прошло нормально.Затем я заметил все большие и большие пробелы в столбце auto_incremented id
и обнаружил, что это связано с оператором INSERT INTO ...
: MySQL пытается выполнить вставку первым.Это когда id
автоматически увеличивается.После увеличения он остается.Затем обнаруживается дубликат и происходит обновление.
Теперь мой вопрос: какое решение по производительности является наилучшим для долгосрочной перспективы?
Вариант A: Установитьстолбец id
в значение без знака INT
или BIGINT
и просто игнорировать пропуски.Проблема здесь в том, что я боюсь ударить по максимуму через пару лет обновления.У меня уже есть значение auto_increment около 12 000 000 для примерно 3 000 000 списков после двух дней обновления ...
Опция B: Переключиться на оператор INSERT IGNORE ...
, проверить затронутые строкии UPDATE ...
при необходимости.
Вариант C: SELECT ...
существующих списков, проверка существования в python и INSERT ...
или UPDATE ...
в зависимости от ситуации.
Любые другие мудрые варианты?
Дополнительная информация: Мне нужна id
для информации, относящейся к listing
сохраненнойв других таблицах (например, listings_images
, listings_prices
и т. д.).ИМХО использование URL (который является уникальным) не будет лучшим вариантом для внешних ключей.
+------------+-------------------+
| Field | Type |
+------------+-------------------+
| listing_id | int(11) unsigned |
| price | int(9) |
| created_at | timestamp |
+------------+-------------------+