Почему параметризованный SQL генерируется NHibernate так же быстро, как хранимая процедура?

StackOverflow https://stackoverflow.com/questions/50346

  •  09-06-2019
  •  | 
  •  

Вопрос

Один из моих коллег утверждает, что, хотя путь выполнения кэширован, параметризованный SQL, сгенерированный из ORM, не может быть таким же быстрым, как хранимая процедура.Любая помощь с этим упрямым разработчиком?

Это было полезно?

Решение

Я бы начал с прочтения этой статьи:

http://decipherinfosys.wordpress.com/2007/03/27/using-stored-procedures-vs-dynamic-sql-generated-by-orm/

Вот тест скорости между этими двумя:

http://www.blackwasp.co.uk/SpeedTestSqlSproc.aspx

Другие советы

Раунд 1 - Вы можете запустить трассировку профилировщика и сравнить время выполнения.

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

Я бы добавил только пару вещей к ответу Роба:

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

Во-вторых, сделайте все остальное равным, за исключением использования запроса, сгенерированного NHibernate, и вызова s'proc.Надеюсь, вы сможете выполнить тест, просто сменив поставщика.

Наконец, поймите, что обычно на карту поставлено гораздо больше, чем просто хранимые процедуры.ОРМ.Имея это в виду, тест должен учитывать все факторы:время выполнения, потребление памяти, масштабируемость, возможность отладки и т.д.

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

Лучшим аргументом в пользу использования хранимых процедур является безопасность.Если вы используете Только хранимые процедуры, с НЕТ в динамическом sql вы можете отключить разрешения SELECT, INSERT, UPDATE, DELETE, ALTER и CREATE для пользователя базы данных приложения.Это защитит вас от большинства SQL-инъекций 2-го порядка, в то время как параметризованные запросы эффективны только против инъекций первого порядка.

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

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

Это происходит так же быстро, если запрос каждый раз один и тот же.Sql Server 2005 кэширует планы запросов на уровне каждого оператора в пакете, независимо от того, откуда поступает SQL.

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

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

Измерьте это.

На самом деле, любая дискуссия на эту тему, вероятно, бесполезна, пока вы не измерите ее.

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

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

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

Даже если хранимая процедура работает на 10% быстрее (вероятно, это не так), вы можете спросить себя, насколько это действительно важно.Что действительно важно, в конце концов, так это то, насколько легко писать и поддерживать код для вашей системы.Если вы кодируете веб-приложение, и все ваши страницы возвращаются за 0,25 секунды, то дополнительное время, сэкономленное при использовании хранимых процедур, ничтожно мало.Однако может быть много дополнительных преимуществ использования ORM, такого как NHibernate, которые было бы чрезвычайно сложно дублировать, используя только хранимые процедуры.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top