Производительность SQL - лучше вставить и повысить исключение или проверку? - PullRequest
4 голосов
/ 16 февраля 2009

Я рассматриваю оптимизацию в особенно тяжелой части моего кода. Его задача - вставить статистические данные в таблицу. Эти данные изрядно бьют по другим программам. В противном случае я хотел бы использовать SQL Bulk и т. Д.

Так что мой вопрос ...

Можно ли попытаться вставить некоторые данные, зная, что они могут (не слишком часто) генерировать исключение SqlException для дублирующейся строки?

Хуже ли производительность исключения исключения, чем проверка каждой строки перед вставкой?

Ответы [ 7 ]

7 голосов
/ 16 февраля 2009

Во-первых, мой совет - ошибаться в сторону правильности, а не скорости. Когда вы закончите свой проект и профилирование покажет, что вы теряете значительный время проверки существования строк перед их вставкой, только , а затем оптимизируйте его.

Во-вторых, я думаю, что есть синтаксис для вставки и пропуска, если есть дубликаты во всех RDBMS, так что это не должно быть проблемой в первую очередь. Я стараюсь избегать исключений как часть обычного потока приложений и оставляю их для действительно исключительных случаев. То есть не рассчитывайте на исключения в БД для обхода логики в вашем коде. Поддерживайте как можно большую согласованность с вашей стороны (код), и пусть исключения из БД указывают только на истинные ошибки.

6 голосов
/ 16 февраля 2009

На чисто производительном уровне быстрее просто вставить данные и обработать ошибку, особенно если ошибка нечастая. Выполнение запроса выбора для проверки дубликата, обработка этого результата и последующая вставка в случае успеха будут значительно медленнее, чем вставка и обработка случайной ошибки. Если оно вызывает исключение, то это будет немного медленнее, поскольку обработка исключений в большинстве языков идет медленно, но обработка исключения будет во много раз быстрее, чем запрос SQL на любом языке.

Как сказал Ассаф, обычно также есть способ явно обрабатывать дубликаты, чтобы вы могли вообще избежать ошибки. Это еще больше повысит производительность и позволит вам четко указать, что вы обрабатываете дубликаты определенным образом.

Решение о том, использовать хранимые процедуры или нет, зависит от вас - это может помочь в повышении производительности за счет использования большего количества логики в вашей базе данных. Это решение, которое вы должны принять. У меня был плохой опыт с этим, но это зависит от РСУБД и языка, который вы используете.

2 голосов
/ 16 февраля 2009

Я не вижу, чтобы хранимая процедура ускорила одноэлементную вставку, если не задействована другая обработка. Хотя могут быть и другие преимущества - хранение всей логики в одном месте и т. Д.

Лично я бы вставил и перехватил ошибку, если есть дубликаты и т. Д.

Если вы выполните проверку IF NOT EXISTS, а затем условно INSERT, существует интервал, в котором транзакция должна удерживать блокировку, что может увеличить блокировку таблицы.

Для занятой таблицы вставки стоит проверить, насколько фрагментированной становится таблица. Если вы вставляете с кластеризованным PK в столбец Identity / Auto-number, тогда все вставки находятся на одном конце (и индекс может иметь коэффициент заполнения 100%), но если вставки являются случайными в кластерном индексе, то могут возникать проблемы с разделением страниц и т. д.

Связанная проблема заключается в том, что статистика в таблице, вероятно, быстро устареет, и это может повлиять на производительность запросов с кэшированными планами запросов и т. Д.

2 голосов
/ 16 февраля 2009

Я думаю, что лучше использовать процедуру магазина и использовать IF

ЕСЛИ (ВЫБЕРИТЕ СЧЕТЧИК (*) ОТ X ГДЕ Y = Z) = 0 ВСТАВИТЬ В (X) ЗНАЧЕНИЯ ('XX') ....

и вы можете добавить условие ELSE ...

0 голосов
/ 13 октября 2018

В среде с высокой нагрузкой проверки, существует ли материал, недостаточно, так как будут условия гонки, и строки будут вставлены между другими существующими проверками. Тогда вам придется либо выполнить блокировку после проверки (которая сама по себе склонна к гоночным условиям), либо снова обработать исключение в случае, если другие данные смогли проникнуть внутрь.

0 голосов
/ 16 февраля 2009

Может быть не очень актуален вопрос здесь.

Но я работал в проекте, где перед программным отбрасыванием таблицы он проверял, существует ли таблица или нет.

Когда мы начали оптимизировать код, мы изменили его для обработки конкретного исключения, а не для проверки существования таблицы перед ее удалением.

И мы значительно улучшили время, так как мы использовали проверку существования довольно много раз в потоке процесса.

Исходя из этого, я полагаю, что обработать исключение дешевле, чем другой запрос в базу данных для проверки.

0 голосов
/ 16 февраля 2009

Да, я бы всегда проверял. например, адрес электронной почты или IP-адрес.

Если вы беспокоитесь о производительности, используйте хранимые процедуры для обработки логики в случае дублирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...