Влияние на производительность с помощью SQL Collation - PullRequest
2 голосов
/ 27 мая 2011

Я просто хотел бы проверить несколько вещей:

Q1) Latin1_General_CI_AS нечувствителен к регистру, чувствителен к акценту: Т.е. SQL будет видеть следующее как равное - "привет" и "ПРИВЕТ"

С LINQ я часто делаю тихо:

db.Where(v => v.Email == "some email".ToLower())

Q2) Предполагая, что мое понимание Q1 верное, я просто трачу время на обработку вызова ToLower () в моих запросах?

Q3)Кто-нибудь знает, будет ли улучшение производительности при использовании Latin1_General_bin по сравнению с Latin1_General_CI_AS?То есть уже были проведены тесты производительности в блоге и т. Д. (Подумал об этом, когда я писал пост, так что пока не выглядел сам))

Ответы [ 2 ]

4 голосов
/ 27 мая 2011

В общем случае сравнения SQL не чувствительны к регистру.
Однако есть исключения, например, в MySQL, если вы используете binary сравнения varchar будут чувствительны к регистру.

Так что ваш ToLower может быть не пустой тратой времени.

Latin1_General_bin чувствителен к регистру.
В то время как Latin1_General_CI_AS - нет.

Сравнение с учетом регистра будет быстрее в базе данных, но вы платите цену, если хотите сопоставить «какое-то электронное письмо» с «Некоторым электронным письмом», которое вам придется преобразовать в нижний регистр, теряя все это увеличение скорости.1012 * Я не рассчитал это, но я не думаю, что это стоит хлопот.
Я рекомендую разумное использование индексов и запросов перед этой микрооптимизацией.

- Преждевременная оптимизацияэто корень зла, Дональд Кнут.

3 голосов
/ 27 мая 2011

Производительность на реальном примере: Таблица Адрес состоит из 320К строк данных. Нам нужен Adres.Id, когда у нас есть электронная почта (как в вашем примере).

Сортировка базы данных (и таблицы адресов): SQL_Latin1_General_CP1_CI_AS

Для оптимизации производительности для столбца Электронная почта был создан некластеризованный индекс (включен столбец Adres.Id)

Запросы выглядят так:

SELECT  Adres.ID,Email FROM  csc.Adres WHERE EMAIL ='23LMDLh6N@f8CyB7vPL.r4L'

SELECT  Adres.ID,Email FROM  csc.Adres WHERE EMAIL='23LMDLh6N@F8CyB7vPL.r4L' COLLATE Latin1_General_bin

1 строка была возвращена для каждого запроса

результаты: enter image description here

Похоже, что во втором случае запрос SQL Server не идентифицирует как SARG. Зачем? Давайте посмотрим на детали. В первом случае:

 ScalarOperator ScalarString="CONVERT_IMPLICIT(nvarchar(4000),[@1],0)

И в секунду:

ScalarOperator ScalarString="CONVERT_IMPLICIT(nvarchar(80),[CSCENTRUMTest].[csc].[Adres].[Email],0)=CONVERT_IMPLICIT(nvarchar(4000),CONVERT(varchar(8000),[@1],0),0)">

Таким образом, во втором случае электронная почта преобразуется в требуемое сопоставление. Этот случай не SARG, и было выполнено сканирование индекса.

Если запросы не могут быть идентифицированы как SARG (например, LIKE '%some email%) ', планы совпадают.

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

Вы можете найти информацию о SARG в различных книгах / статьях по настройке производительности.

...