Нечувствительность к регистру SQL Server
Каковы преимущества/недостатки использования нечувствительной к регистру сортировки в SQL Server (с точки зрения производительности запросов)?
У меня есть база данных, которая в настоящее время использует учетную запись без учета регистра, и мне это не очень нравится. Я бы очень хотел изменить его на чувствительный к регистру. Что мне следует знать при изменении сортировки?
Ответы
Ответ 1
(Я добавил это как отдельный ответ, потому что он существенно отличается от моего первого.)
Хорошо, нашел некоторые фактические документы. Эта статья статьи MS KB говорит, что существуют различия в производительности между разными сортировками, но не там, где вы думаете. Разница между SQL-сопоставлениями (совместимость с обратной совместимостью, но не с поддержкой unicode) и сопоставление Windows (с поддержкой unicode):
Как правило, степень разницы в производительности между сопоставлениями Windows и SQL не будет значимой. Разница возникает только в том случае, если рабочая нагрузка связана с ЦП, а не ограничена вводом-выводом или скоростью сети, и большая часть этой нагрузки на процессор обусловлена накладными расходами на манипуляции или сопоставление строк, выполняемые в SQL Server.
Оба сопоставления SQL и Windows имеют чувствительные к регистру и нечувствительные к регистру версии, поэтому, похоже, это не является основной задачей.
Еще одна хорошая история "из окопов" в Дэне превосходная статья под названием " Collation Hell:
Я унаследовал смешанную среду сопоставления с большим количеством сортировок, чем я могу рассчитывать с одной стороны. Для разных сопоставлений требуются обходные пути, чтобы избежать ошибок "не удается разрешить конфликты сортировки", и эти обходные пути убивают производительность из-за несогласованных выражений. Работа со смешанными сортировками - настоящая боль, поэтому я настоятельно рекомендую вам стандартизировать один синтаксис и отклоняться только после тщательной оценки.
Он заключает:
Я лично не думаю, что производительность должна даже учитываться при выборе правильной сортировки. Одна из причин, по которой я живу в ассемблере коллаборации, заключается в том, что мои предшественники выбрали бинарные сопоставления, чтобы выработать каждую битку производительности для наших высококонвертируемых OLTP-систем. За исключением исключительного поиска подстановочных таблиц, я не обнаружил заметных различий в производительности с нашими разными сопоставлениями. Реальным ключом к производительности является настройка запросов и индексов, а не сортировка. Если производительность важна для вас, я рекомендую вам выполнить тест производительности с вашими фактическими запросами приложений, прежде чем выбирать сортировку в зависимости от ожидаемых результатов.
Надеюсь, что это поможет.
Ответ 2
Если вы измените настройку в базе данных, вы также должны изменить ее на каждый столбец отдельно - они поддерживают настройку сопоставления, которая была в силе, когда их таблица была создана.
create database CollTest COLLATE Latin1_General_CI_AI
go
use CollTest
go
create table T1 (
ID int not null,
Val1 varchar(50) not null
)
go
select name,collation_name from sys.columns where name='Val1'
go
alter database CollTest COLLATE Latin1_General_CS_AS
go
select name,collation_name from sys.columns where name='Val1'
go
Результат:
name collation_name
---- --------------
Val1 Latin1_General_CI_AI
name collation_name
---- --------------
Val1 Latin1_General_CI_AI
Ответ 3
Я бы сказал, что самый большой недостаток перехода на чувствительную к регистру сортировку в производственной базе данных будет заключаться в том, что многие, если не большинство, ваши запросы будут терпеть неудачу, потому что в настоящее время они предназначены для игнорирования дела.
Я не пытался менять сортировку на существующую базу данных, но я подозреваю, что это тоже может потребовать много времени. Вероятно, вам придется полностью заблокировать пользователей, пока процесс тоже произойдет. Не пытайтесь это делать, если вы не прошли тщательную проверку на dev.
Ответ 4
Если вы изменяете сортировку базы данных, но не сортируете сервер (и тогда они не совпадают в результате), следите за использованием временных таблиц. Если в их заявлении CREATE не указано иное, они будут использовать настройку по умолчанию сервера, а не базу данных, которая может вызвать JOINs или другие сравнения с вашими столбцами БД (при условии, что они также изменены на сортировку БД, как указано в Damien_The_Unbeliever) сбой.
Ответ 5
Я не могу найти что-либо, чтобы подтвердить, работают ли правильно сконструированные запросы быстрее в базе данных с учетом регистра и без учета регистра (хотя я подозреваю, что разница незначительна), но мне несколько понятны:
- Если ваши бизнес-требования не требуют этого, вы ставите себе на себя большую часть дополнительной работы (это суть как ответов HLGEM, так и Damien_The_Unbeliever).
- Если ваши бизнес-требования не требуют этого, вы настраиваете себя на множество возможных ошибок.
- Слишком легко построить плохо выполняемые запросы в базе данных без учета регистра, если требуется поиск с учетом регистра:
Запрос типа:
... WHERE UPPER(GivenName) = 'PETER'
не будет использовать индекс в поле Имя. Вы бы подумали что-то вроде:
... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
будет работать лучше, и это произойдет. Но для максимальной производительности вам нужно будет сделать что-то вроде:
... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
AND GivenName LIKE 'PETER'
(подробности см. в этой статье)