14.09.2007, 14:56 | #1 |
Участник
|
Сомнение возникло в рекомендации "нужно использовать collation, который позволяет хранить в юникоде (например, Cyrilic_General_CI_AS)"
Уважаемые знатоки!
Вопрос возник по настройкам 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()) второй селект - с преобразованием 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()) Пример 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 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 |
|
Теги |
collation, sql server, производительность |
|
|