Как оптимизировать проверку в базе наличия записи (чтобы не сделать дубль)?
Имеется одна таблица(примерно 15 полей) в которой сейчас порядка 50 млн. записей. Каждый день в эту таблицу записывается еще порядка 100 тыс. записей. При этом при записи в таблицу приходится проверять на наличие такой записи в базе, чтобы не было дублей. Все это происходит в рамках MySQL. Индекс простроен только по некоторым полям, по которым потом осуществляется поиск. А проверка на дубль происходит по всем полям, что соответсвенно является самой долгой операцией.
Подскажите, знающие люди, как можно избавиться от этого узкого места? Может меня спасти уход от MySQL на что-то другое, может даже NoSQL? Или только индекс по всем полям?
Добавь ещё одно индексное поле с md5(все данные таблицы) и при проверке на дубль сравнивай хеши.
SELECT 1 FROM table WHERE hash='5c331a6790ba2d61a5c372336c9d215e'
Эээ, как бы уникальный ключ для того и создан, настораживает только, что у вас уникальными должны быть все поля, возможно, база плохо спроектирована. Может, при ваших объемах это решение не пойдет, но как минимум оно очевидно и с него стоит начать.
Ответ на Ваш вопрос будет сильно зависеть от того, зачем вы проверяете на наличие имеющейся записи? Если для того чтобы сделать INSERT если записи нет и UPDATE если запись уже есть, то возможно вам стоит применить конструкцию ON DUPLICATE KEY, тем самым сможете во-первых возложить проверку на БД, во вторых, получите возможность лить данные пачкой, и в третих уберете лишний оверхед появляющийся от позаписного исполнения.
Сейчас это делает так: SELECT 1 FROM table WHERE… И если ничего нет, то INSERT, а если есть то ничего не делаем. Просто в данных которые обрабатываются и заливаются очень много дублирующихся записей.
В случае INSERT IGNORE нужно будет строить индекс по все таблице или иметь какое-то уникальное поле однозначно определяющее запись. Т.е. его имеет смысл использовать с первым предложенным решением.
как минимум должно быть одно ключевое поле. Просто делаете вставку записи и проверяете результат операции на возникновение ошибки — в таком случае запись уже есть. Или просто игнорируете ошибку.
ЗЫ: я хоть и разработчик и сделал бы именно так, но не уверен, что это концептуально правильное решение.