Что быстрее найти повторы? - PullRequest
0 голосов
/ 05 июля 2011

У меня есть таблица с 1 столбцом, и я хочу проверить повторение значения между 10 000 доступных строк.

Я думаю, у меня есть два варианта:

Сделать запрос, используя оператор 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 ]

1 голос
/ 05 июля 2011

Здесь нет общего ответа, это зависит от того, как настроена ваша схема.В большинстве (возможно, во всех?) Реляционных базах данных создание поля Primary Key автоматически создаст индекс для этого поля.И проверка уникальности по индексу выполняется так же быстро, как вы можете получить в этом случае.

Но вы можете индексировать свое поле, не объявляя его Primary Key вашей таблицы.И если вы сделаете это, команда SELECT будет такой же быстрой, как и метод INSERT plus catch.В более широком смысле, вы можете иметь только один Primary Key на таблицу, поэтому сделать поле Primary Key не очень надежным решением.Он сломается, как только у вас будет несколько полей, для которых вы хотите применить уникальность (если вы не создадите составной первичный ключ для обоих полей ... но я отступлю, и это в любом случае не обеспечит уникальность для каждого столбца).

Поэтому я бы порекомендовал создать индекс для вашего поля / столбца, а затем с помощью метода SELECT проверить, существует ли значение.Кроме того, вы можете индексировать поле и указать, что оно должно быть уникальным, без , сделавшим его вашим Primary Key, и использовать INSERT plus catch.

1 голос
/ 05 июля 2011

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

1 голос
/ 05 июля 2011

Я бы рекомендовал использовать select count:

Var = Query('SELECT count(*) FROM Table WHERE Field1="VALUE"');

if (Var > 0) MessageBox("This value exists in the table");

Второй подход не очень хорош, IMO, и, вероятно, будет намного медленнее.И кстати, он должен читать существует вместо существовать : -)

...