Что быстрее найти повторения?
У меня есть таблица с 1 столбцом, и я хочу проверить повторение значения между 10000 доступных строк.
Я думаю, что у меня есть два варианта:
Сделайте запрос, используя SELECT
утверждение, как это:
Var = Query('SELECT * FROM Table WHERE
Field1="VALUE"');
if (Var <> null)
MessageBox("This value exists in the table");
Установить мой столбец как Primary Key
и использовать INSERT
утверждение, как это:
try {
Var = Query('INSERT INTO Table(Field1) VALUES("VALUE")');
}
catch {
MessageBox("This value exists in the table");
}
Что быстрее?
3 ответа
Здесь нет общего ответа, это зависит от того, как настроена ваша схема. В большинстве (возможно, во всех?) Реляционных базах данных поле Primary Key
автоматически создаст индекс для этого поля. И проверка уникальности по индексу выполняется так же быстро, как вы можете получить в этом случае.
Но вы можете индексировать свое поле, не объявляя его Primary Key
, И если вы сделаете это SELECT
Команда будет так же быстро, как INSERT
плюс метод ловли. В более широком смысле, вы можете иметь только один Primary Key
за столом, поэтому поле Primary Key
не очень надежное решение. Он сломается, как только у вас будет несколько полей, для которых вы хотите применить уникальность (если вы не создадите составной первичный ключ для обоих полей... но я отступлю, и это в любом случае не обеспечит уникальность для каждого столбца).
Поэтому я бы рекомендовал создать индекс для вашего поля / столбца, а затем использовать SELECT
метод, чтобы увидеть, если значение уже существует. Кроме того, вы можете индексировать поле и указать, что оно должно быть уникальным, не делая его вашим Primary Key
и использовать INSERT
плюс подвох.
Я бы рекомендовал использовать выбор счетчика:
Var = Query('SELECT count(*) FROM Table WHERE Field1="VALUE"');
if (Var > 0) MessageBox("This value exists in the table");
Второй подход не так хорош, IMO, и, вероятно, будет намного медленнее. И кстати, он должен читать существует, а не существовать:-)
Если вы хотите вставить значение, если оно не существует, наиболее подходящим будет что-то вроде следующего (хотя могут применяться разные диалекты SQL):
INSERT INTO Table(Column)
SELECT 'New Value' WHERE NOT EXISTS (SELECT * FROM Table where Column = 'New Value')
И затем проверка, были ли затронуты 0 или 1 ряд.
Обратите внимание, где я говорю наиболее целесообразно, я не делаю оценку производительности. Я говорю о коде, который наиболее четко выражает намерение. Обычно это будет достаточно хорошо. Лишь в редких случаях вы должны отойти от кода, который наиболее четко выражает ваши намерения, на что-то менее ясное, которое работает на 0,5% лучше...
Вы также должны остерегаться вашего первого формата (SELECT * FROM TABLE...
), как общий стиль. Если вы запрашивали большую, широкую таблицу, выполнение такого выбора может привести к тому, что база данных выполнит большой объем операций ввода-вывода, чтобы получить все значения столбцов, просто чтобы ваш код затем игнорировал все эти значения. SELECT *...
в предложении EXISTS, с другой стороны, он специально обрабатывается большинством механизмов баз данных и не будет извлекать фактические данные строки / столбца.