Я уже писал, что при работе с базами данных предпочитаю Dapper и его я достаточно серьезно затрагивал в своей электронной книге по большим сайтам. Вчера нашел в Dapper большой недостаток для тех, кто использует varchar строки.
Не все еще перешли на Unicode и некоторые до сих пор используют varchar, хотя давно уже пора перейти на nvarchar. Проблема в том, что Dapper в качестве строк использует как раз nvarchar, а Transact-SQL оказывается не очень дружит с преобразованиями строк.
Допустим, что у вас есть таблица и поле Firstname типа varchar. Если таблица большая, достаточно даже миллиона строк, и SQL сервер может упасть даже под небольшим натиском простого запроса:
Declare @s nvarchar Set @s = 'test' Select * from Table where Firstname = @s
Даже при наличии индекса этот запрос может выполнятся непредсказуемым образом. При выполнении обновления строки план выполнения у меня показал, что сервер будет делать скан индекса по Email, и только потом полезет в индекс по имени. Я был реально в шоке, когда я это увидел.
Проблема решается просто - нельзя использовать nvarchar строки, если поле простой varchar и если модифицировать запрос так, то он выполняется быстро и использует индексы правильно:
Declare @s nvarchar Set @s = 'test' Select * from Table where Firstname = cast(@s as varchar)
Всего лишь банальное приведение строки позволяет вернуть план выполнения запроса к разумному. А ведь оптимизатор запросов SQL Server может сделать это преобразование сам. Ведь когда сравнивается две строки, есть два решения - преобразовать искомое значение к типу поля или преобразовывает все значения в таблице к искомому. Какой выбрал путь SQL Server - я понятия не имею.
Я в основном пишу сайты для американцев и до сих пор использую varchar (не мое решение), поэтому на эту проблему производительности как-то не натыкался. Но тем, кто работает с SQL Server - будьте осторожны. Создавайте параметры именно того типа, который вам нужен, помните, что varchar и nvarchar хоть и взаимозаменяемые, но с точки зрения производительности замену лучше не делать.
Проблема еще в том, что строка string в .NET мапится сразу на оба типа строк базы данных. Если же нужно явно указать принадлежность к varchar (не юникод), нужно использовать AnsiString
Более очевидная проблема может быть с конфликтом строки и числа.
Declare @s int Set @s = 111 Select * from Table where FieldName = @s
Такой запрос абсолютно легален, если в поле FieldName только числа, то запрос будет выполнен, даже если тип поля строковй, но только он будет на много медленней, чем если объявить переменную как строку. Тип строки и тип параметра должны четко совпадать, иначе это сильно бъет по производительности системы.
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым
да, я отаком и неподозревал
На счет последнего примера:
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.