Что быстрее найти повторения?

У меня есть таблица с 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, с другой стороны, он специально обрабатывается большинством механизмов баз данных и не будет извлекать фактические данные строки / столбца.

Другие вопросы по тегам