Ответ 1
Ищите объяснение для этого.
NVarchar имеет 16 бит, а правила сравнения Unicode намного сложнее, чем ASCII - специальные символы для разных языков, которые поддерживаются в то же время, требуют котировки еще нескольких обработок.
Посмотрите следующий пример. Он показывает, что поиск в строке unicode (nvarchar) почти в восемь раз хуже, чем поиск в строке varchar. И наравне с неявными преобразованиями. Ищете объяснение этого. Или способ поиска в строках nvarchar более эффективно.
use tempdb
create table test
(
testid int identity primary key,
v varchar(36),
nv nvarchar(36),
filler char(500)
)
go
set nocount on
set statistics time off
insert test (v, nv)
select CAST (newid() as varchar(36)),
CAST (newid() as nvarchar(36))
go 1000000
set statistics time on
-- search utf8 string
select COUNT(1) from test where v like '%abcd%' option (maxdop 1)
-- CPU time = 906 ms, elapsed time = 911 ms.
-- search utf8 string using unicode (uses convert_implicit)
select COUNT(1) from test where v like N'%abcd%' option (maxdop 1)
-- CPU time = 6969 ms, elapsed time = 6970 ms.
-- search unicode string
select COUNT(1) from test where nv like N'%abcd%' option (maxdop 1)
-- CPU time = 6844 ms, elapsed time = 6911 ms.
Ищите объяснение для этого.
NVarchar имеет 16 бит, а правила сравнения Unicode намного сложнее, чем ASCII - специальные символы для разных языков, которые поддерживаются в то же время, требуют котировки еще нескольких обработок.
Я предполагаю, что LIKE
реализуется с использованием алгоритма O (n ^ 2) в отличие от алгоритма O (n); вероятно, это должно быть для того, чтобы ведущий %
работал. Поскольку строка Юникода в два раза длиннее, это похоже на ваши номера.
Поиск LIKE %% реализуется как > и <, Теперь больше количества строк, больше времени обработки, чем SQL, не может эффективно использовать статистику для поисковых запросов %%.
Кроме того, поиск в Unicode требует дополнительного хранения и наряду с осложнениями сортировки, он, как правило, не так эффективен, как обычный варильский ванильный поиск. Самый быстрый поиск сопоставлений, который вы наблюдали, - это поиск в двоичном сопоставлении.
Эти поисковые запросы лучше всего подходят для полнотекстового поиска или реализованы с использованием FuzzyLookup с хэш-таблицей в памяти, если у вас много ОЗУ и довольно статическая таблица.
НТН
Я видел подобные проблемы в SQL Server. Был случай, когда я использовал параметризованные запросы, а моим параметром был UTF-8 (по умолчанию в .net), и поле было varchar (а не utf-8). Закончилось преобразование каждого значения индекса в utf-8 только для простого поиска индекса. Это может быть связано с тем, что вся строка может быть переведена на другой набор символов для сравнения. Также для nvarchar "a" будет таким же, как "& aacute"; это означает, что там еще много работы, чтобы выяснить, равны ли 2 строки в юникоде. Кроме того, вы можете использовать полнотекстовую индексацию, хотя я не уверен, что это решает вашу проблему.