Уважаемые знатоки!
Вопрос возник по настройкам SQLServer'а 2005 под Axapta (3) в связи с тем, что неоднократно видел рекомендации хранить текстовые данные в collation Cyrilic_General_CI_AS.
Если вкратце - ситуация возникла такая -
ставятся эксперименты по повышению производительности
Исторически сложилось, что collation таблиц рабочей БД - General_Latin1_1251_CI_AS.
Как и описано на форумах, при этом иногда возникает ситуация, когда из-за этого не используются имеющиеся индексы и вместо index seek в плане - table scan + compute scalar по тесктовому полю с collation General_Latin1_1251_CI_AS
Если перенести данные в таблицы с рекомендуемой гуру collation Cyrilic_General_CI_AS ситуация исправляется, и время выполнения запросов select top 1 ... по индексам с текстовыми полями уменьшается на пару порядков.
Но есть одно неприятное "НО"...
При этом время выполнения большинства остальных запросов увеличивается раза в 2
И, субъективно, общая усредненная скороость выполенения запросов падает на 20 - 30%
пара примеров
Пример 1.
по преобразованной к Cyrilic_General_CI_AS таблице делается 2 select'а (причем, эксперименты ставились на разных экземплярах сервера и БД с разными collation сервера и БД по умолчанию и результаты опытов от этих параметров не зависят, как оказалось)
первый селект - в родном collation Cyrilic_General_CI_AS
Цитата:
declare @d datetime
set @d =getdate()
select *
from
SalesPickingListJournalLine sl with ( nolock)
where charindex ( ltrim ( rtrim ( sl . PickingListId ) ) , ',01Н0002320') > 0
select db_name(),getdate(), @d, datediff(ms,@d,getdate())
результат - 630 мс, чистый table scan
второй селект - с преобразованием collation выражения к General_Latin1_1251_CI_AS
Цитата:
declare @d datetime
set @d =getdate()
select *
from
SalesPickingListJournalLine sl with ( nolock)
where charindex ( ltrim ( rtrim ( sl . PickingListId collate SQL_Latin1_General_CP1251_CI_AS) ) , ',01Н0002320' ) > 0
select db_name(),getdate(), @d, datediff(ms,@d,getdate())
результат - уже 270 мс, точно такойже чистый table scan с таким же cost'ом выполнения
Пример 2.
сравнение времени выполнения более сложного запроса в оригинальной БД (collate SQL_Latin1_General_CP1251_CI_AS) и в преобразованной к collation Cyrilic_General_CI_AS на том же железе
текст запроса (профайлер помог)
Цитата:
SELECT A.ITEMID
FROM INVENTTABLE A WITH( NOLOCK),INVENTSUM B WITH( NOLOCK),INVENTDIM C WITH( NOLOCK)
WHERE ((A.DATAAREAID='DAT') AND (A.A_LINECODE ='CIS'))
AND ((B.DATAAREAID='DAT') AND (((B.CLOSED=0) AND (B.CLOSEDQTY=0)) AND (A.ITEMID =B.ITEMID )))
AND ((C.DATAAREAID='DAT') AND ((C.INVENTPROJECTID ='ОЧЕРЕДЬ') AND (B.INVENTDIMID=C.INVENTDIMID)))
GROUP BY A.ITEMID
ORDER BY A.ITEMID
OPTION(FAST 3)
при collation SQL_Latin1_General_CP1251_CI_AS среднее время выполнения - 200мс
при collation Cyrilic_General_CI_AS среднее время выполнения - 700мс
(перестройки индексов, статистик, танцы с бубном и пр. - все делалось)
Причем такая ситуация с большинством отловленных профайлером запросов- если не в 2-3 раза, то в 1.5 раза медленнее Cyrilic_General_CI_AS (хотя косты запросовв планах - одинаковые)
И, выходит, если оставить старый collation SQL_Latin1_General_CP1251_CI_AS - то
можно хотя бы обойти неиспользование индексов вводом вычисляемых полей вида
TERTIARY_WEIGHTS(TEXT_FIELD1) (это то, на что заменается compute scalar'ом в плане использование текстового поля) и постройке индексов по ним, хоть это и очень "кривое" решение, а вот сделать с гарантированным падением скорости в 1.5 раза при смене collation на Cyrilic_General_CI_AS ничего не получается.
В чем я мог ошибиться при экспериментах?
Или - пусть хоть и медленнее, но технологичней с Cyrilic_General_CI_AS?
С уважением,
Виталий
PS:
SQL2005 SP1
немного доп. информации по экспериментам -
http://www.sql.ru/forum/actualthread...6&pg=2#4663453