|
|
-
Довольно часто приходится слышать то, что различие между табличными переменными и временными таблицами заключается в том, что первые всегда хранятся в памяти, а последние в tempdb. Но на самом деле это миф. И временные таблицы, и табличные переменные, создаются в tempdb (так как обязательно должно быть постоянное хранилище данных, на случай, если памяти всё же не хватит). Убедиться в том, что табличные переменные создаются в tempdb так же, как и временные таблицы, можно проделав вот такой опыт: SELECT COUNT(*) FROM tempdb.sys.tables; GO DECLARE @table_var table(id int); SELECT COUNT(*) FROM tempdb.sys.tables; GO
Результат выполнения 2-го COUNT(*) будет на 1 больше чем первого. Следовательно, в результате объявления табличной переменной в tempdb создалась таблица, и в способе хранения данных они не особо отличаются. Давайте теперь посмотрим на отличия табличных переменных от временных таблиц:
Преимущества:
- Автоматически очищаются в конце функции, хранимой процедуры или пакета, где они были определены
- При использовании в хранимых процедурах табличных переменных приходится прибегать к рекомпиляциям реже, чем при использовании временных таблиц
- Транзакции с использованием табличных переменных продолжаются только во время процесса обновления соответствующих табличных переменных. Поэтому табличные переменные реже подвергаются блокировке и требуют меньших ресурсов для ведения журналов регистрации
- Табличной переменной можно присвоить результат выполнения табличной функции, для повторного использования результатов
- Табличную переменную можно передавать как параметр в хранимую процедуру (SQL Server 2008)
Недостатки:
- На табличных переменных нельзя создавать некластерные индексы
- Табличные переменные не содержат статистику
- Табличные переменные не могут использоваться в INSERT EXEC или SELECT INTO
- Запросы, изменяющие табличные переменные, не создают параллельных планов выполнения запроса
Общие рекомендации Microsoft, относительно использования табличных переменных таковы: "Используйте их везде, где это возможно, кроме тех случаев, когда у вас хранятся значительные объёмы данных, и присутствует повторное использование таблиц". Кроме того, отмечено, что сценарии использования могут быть разными, и в каждом конкретном случае нужно смотреть и пробовать что вам больше подходит.
Ссылки по теме:
- Табличные переменные (MSDN)
- Временные таблицы
- FAQ по использованию табличных переменных
- Блог Kimberly Tripp
- Блог Ken Simmons
- Блог Pinal Dave
Денис Резник
LPP Soft, .Net Team Lead
Харьков, Украина
|
-
-
-
Недавно один из членов моей комманды задал мне вопрос: "Почему генерация случайных чисел в .Net упорно выдаёт не рэндомные значения, а повторяющиеся?". И последовательный вызов вот такого метода, всегда генерирует одну и ту же последовательность чисел: 1: const string AllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2:
3: public static string GenerateRandomString(int length)
4: {
5: string randomString = String.Empty;
6: Random random = new Random();
7: for (int i = 0; i < length; i++)
8: randomString += AllowableCharacters[random.Next(AllowableCharacters.Length)];
9:
10: return randomString;
11: }
Случай меня заинтересовал, и я полез в рефлектор чтобы понять причину такого поведения. Вот, что я там увидел:
1: public Random() : this(Environment.TickCount) {}
Наверное ни для кого не секрет, что генерация случайных чисел в .Net (и не только в .Net) базируется на использовании некоего начального значения, которое должно быть уникальным. Для получений таких значений часто используется уникальная, в данном контексте, метка времени. Как видно из кода, конструктор по умолчанию, в качестве такого, значения использует Environment.TickCount - время, прошедшее со старта приложения, в миллисекундах. Т.е. получается, что если ваши объекты Random создаются с интервалом меньше миллиcекунды, при помощи конструктора по умолчанию – они будут инициализированы одним и тем же параметром, что в свою очередь влечёт генерацию одинаковых последовательностей "случайных" чисел.
На форумах можно встретить несколько вариантов решения проблемы, таких как передачу в конструктор более мелкого промежутка времени (например DateTime.Now.Ticks), задержка между вызовами методов при помощи Thread.Sleep. Но исходя из всего вышесказанного, наилучшим варантом, гарантирующим генерацию случайных чисел, является использование одного экземпляра класса Random:
1: public static string GenerateRealRandomString(int length, Random random)
2: {
3: string randomString = String.Empty;
4: for (int i = 0; i < length; i++)
5: randomString += AllowableCharacters[random.Next(AllowableCharacters.Length)];
6:
7: return randomString;
Где вызов метода, осуществляется таким образом:
1: Random random = new Random();
2: Console.WriteLine(GenerateRealRandomString(10, random));
3: Console.WriteLine(GenerateRealRandomString(10, random));
Материалы поста:
- Насколько случайным бывает Random
Ссылки по теме:
Denis Reznik
LPP Soft, .Net Team Lead
Kharkov, Ukraine
|
-
-
Наверняка это уже не новость, и поисковики пестрят кучей заметок на эту тему, но всё же что это? Да ещё и с таким интригующим названием :) Вот цитата из новостной леты: “На прошлой неделе Инна Фрид (Ina Fried) из CNET News.com заявила в сети об обнаружении в Windows 7 скрытой возможности, которая получила название “режима бога” или GodMode. И хотя в действительности никаких божественных привилегий эта возможность не дает, ее использование может понравиться некоторым пользователям.” Чтобы включить “режим бога” нужно создать на рабочем столе новую папку и назвать её “GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}”. В результате чего значок папки изменится, и по двойному клику откроется окно, содержащее все элементы панели управления нижнего уровня в одном месте: В семёрке этот трюк проделывается без проблем. В теории (не пробовал) должно работать на 32-х битных Vista и Server 2008. “Божественного”, как видите, здесь ничего нет, но то, что это возможность скрытая, да и само название “GodMode” подогревает интерес, согласитесь :) Но, на самом деле, эта возможность не совсем скрытая. Элементам панели управления присвоены канонические имена для программного запуска этих элементов, и использовав вот такой гуид в имени папки - {E2E7934B-DCE5-43C4-9576-7FE4F75E7480} можно получить на своём рабочем столе натройки даты и времени. Недокументировано только само каноническое имя - {ED7BA470-8E54-465E-825C-99712043E01C} (поиск по MSDN выдал только ссылки на блоги). А громкое название в имени папки, тоже можно заменить на что-то другое, например “test.{ED7BA470-8E54-465E-825C-99712043E01C}” даст нам тот же “режим бога” только с именем “test” :) Ссылки по теме: - Блог открывателя “режима бога” - Блог SQLDenis - Лента новостей winline.ru - Канонические имена элементов панели управления - Использование папок для доступа к элементам панели управления
|
-
Не знаю как вам, а мне очень нравятся различные codenames, которые Microsoft даёт своим продуктам во время разработки. Над происхождением их никогда особо не задумывался, но, как оказалось, берутся они не с потолка, и в именовании продуктов есть определённый смысл. Вот, например, кодовые имена известных вам семейств продуктов Microsoft: | Windows Client | | Product | Codename | | Windows XP | Whistler | | Windows Vista | Longhorn | | Windows 7 | Blackomb | | Windows XP Starter Edition | Creekside | | Development Tools | | Product | Codename | | Visual Studio 2005 | Whitbey | | Visual Studio 2008 | Orcas | | Visual Studio Team System 2008 | Rosario | | Visual Studio 2010 | Hawaii | Из этих таблиц видно, что кодовые имена продуктов семейства Windows – это названия горнолыжных курортов. А имена семейства Development Tools – названия островов. Интересно, правда? В своём вебкасте Mary Jo Foley (Microsoft Codename Queen) более подробно рассказывает о политике присвоения codenames продуктам Майкрософт: Более подробно об истории этих и многих других codenames, можно узнать из серии постов “Microsoft Codenames” в блоге Mary Jo Foley - http://xtourl.com/22li. Ссылки по теме: - Серия постов, посвящённым Microsoft Codenames - Список различных codenames - Вебкаст Mary Jo Foley “Microsoft code names explained”
|
-
После своего поста, рассказывающего о том, как можно оптимизировать подсчёт строк в таблице, мне несколько раз задавали вопрос о том, как работает COUNT. И теперь, я хочу поделиться этой ценной информацией. Функция подсчёта строк, всегда пробегает по всем записям таблицы, т.е. последовательно их перебирает в памяти (если не используется условие WHERE). С этим связан довольно распространённый миф: “COUNT(имя_поля) лучше использовать чем COUNT(*), т.к. мы явно указываем по какому полю делать перебор, и в этом случае оптимизатор будет использовать индекс”. На самом деле это не так. Если для таблицы созданы индексы, то перебирается листовой уровень индекса с наименьшим размером ключа, таким образом оптимизатор сам выбирает наиболее оптимальный план выполнения, в независимости от того, что вы указываете в условии COUNT. В этом можно убедиться, запустив пару скриптов. Вначале создадим тестовую таблицу, заполним её данными и создадим необходимые для теста индексы (если вставить в таблицу меньшее количество записей (например 100), то использоваться будет IDX_BIG (думаю в этом случае оптимизатору просто не хватает информации)): CREATE TABLE dbo.Test
(Id int NOT NULL IDENTITY(1,1) PRIMARY KEY, SmallField tinyint NOT NULL, BigField bigint NOT NULL)
GO
CREATE INDEX IDX_SMALL ON dbo.Test(SmallField)
GO
CREATE INDEX IDX_BIG ON dbo.Test(BigField)
GO
INSERT INTO dbo.Test VALUES(1, 2)
GO 1000
И выполним инструкции COUNT в различном формате:
SELECT COUNT(*) FROM dbo.Test
GO
SELECT COUNT(BigField) FROM dbo.Test
GO
SELECT COUNT(1) FROM dbo.Test
GO
Из планов выполнения видно, что в любом случае используется наименьший индекс IDX_SMALL:
Если удалить IDX_SMALL, то будет сканироваться IDX_BIG, т.к. в этом случае он станет самым маленьким. Если же удалить и его, будет сканироваться первичный ключ таблицы. В данном примере показан пример полного сканирования таблицы. Если у вас есть конкретное условие WHERE или поля NULL, то в запросе будет использоваться индекс указанного в запросе поля.
PS: Думаю выкладывать скрипты, планы выполнения, и другие материалы используемые в постах, в свой Sky Drive - http://xtourl.com/22et
Ссылки по теме:
- Блог Пола Рэндала
- Блог Аарона Альтона
- Функция COUNT
- Альтернатива COUNT(*)
- Материалы поста
|
-
-
27 ноября состоялась очередная встреча UNETA, на которой я выступал с докладом о “SQL Azure Database”. В докладе был представлен обзор имеющихся возможностей, принципов работы, истории продукта, направлений развития, а также описана стратегия вывода продукта на рынок. Материалы доклада находятся здесь - http://xtourl.com/229d. И, в заключение, чтобы пост не получился таким скучным, хочу привести несколько наиболее актуальных вопросов, заданных в ходе доклада: - Когда планируется выход продукта на рынок? С 1-го января SQL Azure Database будет доступна для промышленного использования в США, странах юго-восточной Азии и северной Европы. У стран СНГ возможность использовать SQL Azure появится позже, но точные даты пока не известны. - Сколько нужно платить за использование? Есть 2 редакции, Web и Business Edition, ограниченные размером базы в 1 и 10 Гб соответственно. Web стоит $9.99 в месяц, Business $99.9 в месяц (хранение данных). Трафик тарифицируется погигабайтно: 10 центов входящий, 15 исходящий. Трафик между приложением, находящимся в Windows Azure и БД в SQL Azure Database не тарифицируется. - Для кого предназначен данный продукт? В таком виде как сейчас SQL Azure Database больше всего подходит для стартапов (за счёт минимальных стартовые денежных вливаний) и для небольших компаний (ограничение на размер базы в 1 и 10 Гб), имеюших географически удалённые филиалы (респределение данных между географически удалёнными серверами). - Чем обусловлено, то, что размер базы ограничен 1 и 10 Гб, для Web и Business Edition соответственно? Ответ с форумов майкрософт был таков, что это обусловлено текущими потребностями рынка и основан на результатах опроса. Но такая ценовая политика это только начало, в дальнейшем она будет двигаться в сторону “Pay as you go”, где пользователи будут платить за те ресурсы, которые они используют. - Есть ли похожие продукты? Да, Amazon уже представил свой продукт общественности, и не за горами предоставление подобных сервисов от Google и других компаний. - Что с защитой данных? Есть ли сейчас какие-нибудь гарантии, того, что мои данные не пропадут? С точки зрения высокой доступности, то уже сейчас есть механизм её поддержания (кроме, непосредственно БД, с которой вы работаете, хранится ещё 2 реплики, одна из которых, в случае падения основной, включается в работу). Важные данные с SQL Azure Database вы можете копировать локально с помощью пакетов SSIS, для предотвращения порчи или потери данных в результате каких-либо действий пользователя. В дальнейшем планируется функционал клонирования БД, позволяющий создвать копию вашей базы по требованию (1 пол. 2010 года) и реализация полноценного бэкапа, с возможностью восстановления данных на конкретный момент времени (2 пол. 2010 года). - Что делать с конфиденциальными данными? Могу ли я доверить их Майкрософт? С точки зрения защиты самих данных от несанкцинированного доступа, есть защита с помощью настраиваемых правил файервола, где вы можете ограничить список IP с которых может быть осуществлён доступ к данным. В то же время, зашиты от “Билла Гейтса” нет, и прозрачного шифрования данных, которое, на мой взгляд, могло бы стать решением этой проблемы, тоже пока нет, но планируется в дальнейшем. Сейчас же вы можете шифровать конфиденциальные данные перед предачей их в облако. Ссылки по теме: - Материалы доклада “SQL Azure Database” - Работа с SQL Azure с помощью SSMS - Сайт SQL Azure - Цены на SQL Azure - SQL Azure developer portal - T-SQL в SQL Azure Database - Блог комманды SQL Azure
|
-
SQL Azure Database – сервис хранения и обработки реляционных данных в облаке или, попросту говоря, “облачная” база данных. Первые версии и демонстрации продукта появились более года назад (тогда он ещё назывался SSDS – SQL Server Data Services), затем продукт был представлен как SQL Data Services на PDC 2008, и, впоследствии, переименован в SQL Azure Database, который в скором времени выйдет в промышленную эксплуатацию. И вот, наконец-то, наряду с возможностью работы с данными с помощью T-SQL команд, с выпуском ноябрьского СTP SQL Server 2008 R2 появилась возможность работать с SQL Server Database с помощью привычного нам инструмента – SQL Server Management Studio, что я конечно же попробовал, и теперь хочу поделиться своим опытом и впечатлениями. Чтобы начать работу с SQL Azure Database нужен аккаунт SQL Azure. Если он у вас уже есть, идём на sql.azure.com, если нет, то можно зарегестрироваться для получения приглашения. После того, как вы вошли в систему с помощью своего Live ID, вы увидите свой сервер. Сервер, в данном случае, не является экземпляром SQL Server, здесь это некая логическая единица. На сервере уже создана одна БД - master: Удалённый доступ к SQL Asure Database по умолчанию отключён. Чтобы включить его нужно перейти на закладку “Firewall Settings” и добавить свой IP в список разрешённых адресов (IP определяется сам, вам только нужно скопировать и вставить его в поле. Мелочь, а приятно :)): Новые настройки файервола вступают в действие через пять минут. Есть возможность расслабиться и почитать что-нибудь про SQL Azure :). Итак, приступаем к работе. Для соединения с сервером нужно скопировать имя сервера с портала, выбрать тип аутентификации SQL Server (Windows аутентификация не поддерживается) и ввести имя пользователя и пароль, указанные вами при создании аккаунта SQL Azure. Если вдруг забудете пароль, его можно будет легко поменять прямо на портале. Первое, что бросается в глаза – отсутствие многих пунктов контекстного меню, при нажатии правой кнопкой на различных узлах в Object Explorer: Для того, чтобы посмотреть на поддержку T-SQL, я сгенерировал студией скрипты БД Northwind, и попытался накатить их на “облачный” сервер, и поработать с “облачной базой”. Итак, первые впечатления: - CREATE DATABASE не поддерживает разбиение на файловые группы (базу также можно создать прямо с портала) - ALTER DATABASE не поддерживается - Поддерживается создание логинов - Не поддерживается переключение контекста с помощью USE (чтобы начать работать в новой, созданной БД, нужно явно открыть соединение с ней) - Поддерживаются DDL команды создания практически всех объектов БД - Настройки индекса при создании не поддерживаются (FILLFACTOR и т.п.) (если из студии сгенерировать скрипт “облачной” БД, то накатить его в облаке будет нельзя, т.к. он содержит и USE и ALTER DATABASE и неподдерживаемые настройки индексов) - Поддерживаются базовые команды T-SQL - В контекстном меню таблицы нет привычного пункта SELECT TOP 1000 rows - Интеллисенс не работает - Поддерживает типы данных SQL Server 2008 (за исключением HierarchyId, Geometry и Geography) - Доступна работа с планами выполнения - При раскрытии узла репликации в Object Explorer, вылетает “Operation not supported”. - Profiler и Activity Monitor недоступны Более подробно об ограничениях текущей версии и о доступных возможностях T-SQL можно прочитать на странице продукта в MSDN. В целом же впечатление остаётся приятное, и работа с SQL Azure кажется чем-то привычным. Текущая версия SQL Azure Database является “feature complete” и большинство её ограничений связано с самим принципом предоставления облачного сервиса (сокрытие физических аспектов от потребителей). И в заключение хочу сказать, что на PDC 2009 была объявлена дата ввода продукта в промышленную эксплуатацию – 1 января 2010 года (для США, стран юго-восточной Азии и северной европы). У нас это будет немного позже. Ещё интересный момент – первый месяц эксплуатации будет бесплатным. Ссылки по теме: - Сайт SQL Azure - SQL Azure developer portal - T-SQL в SQL Azure Database - Блог комманды SQL Azure - По дороге с облаками - SQL Azure – MSDN - SQL Server 2008 R2 Management Studio Download - Brent Ozar blog - Видео с PDC 2009, содержащее тэг “SQL Azure”
|
-
На больших объёмах данных (миллионы записей), функция COUNT(*) может выполняться минуты, и время получения количества записей будет расти по мере роста таблицы. А хотелось бы моментально получить результат. В этом посте я хочу рассказать о маленьком трюке, позволяющем получить количество строк таблицы в считанные доли секунды. Идея быстрого получения кол-ва строк заключается в том, чтобы не вызывать функцию COUNT, обращающуюся к записям в таблице или индексе, а обратиться к месту в котором хранится количество строк таблицы. В SQL Server 2000 таким местом являлась системная таблица sysindexes, которая присутствует и в 2008 (также было добавлено системное представление sys.sysindexes), но оставлена только для обеспечения обратной совместимости. Поэтому я предлагаю воспользоваться средством, которое есть в SQL Server 2008, и вполне годится для таких целей – динамическим представлением sys.dm_db_partition_stats, содержащим данные о страницах и строках таблиц: SELECT s.row_count
FROM sys.dm_db_partition_stats s
WHERE s.object_id = OBJECT_ID('my_table')
AND s.index_id < 2
Если таблица секционирована, то придётся это тоже учесть:
SELECT SUM(s.row_count) AS row_count
FROM sys.dm_db_partition_stats s
WHERE s.object_id = OBJECT_ID('my_table')
AND s.index_id < 2
GROUP BY s.object_id
На моей полуторамиллионной таблице визуально разница составляет пару секунд. И вот, что говорит план выполнения:

Основной плюс такого подхода, то, что время выполнения запроса – величина константная, а при использовании COUNT, время будет расти пропорционально количеству добавляемых записей.
Ссылки по теме:
- Подсчёт строк с помощью sysindexes
- Альтернативные способы подсчёта строк
- Функция COUNT
- Cистемное представление sys.dm_db_partition_stats
- Cистемное представление sys.sysindexes
|
-
Совсем надавно стал доступен для загрузки следующий CTP SQL Server 2008 R2. Сегодня его уже могут скачать подписчики TechNet и MSDN, а завтра он станет доступен широким массам. Ноябрьский CTP является “feature complete”, т.е.всё, что будет в релизе, можно посмотреть уже сейчас (но не факт, что всё будет работать как в релизе :)). Итак, новинки CTP: - Поддержка Windows Server 2008 R2, включая Hyper-V с Live Migration - Улучшение сжатия Unicode данных, за счёт реализации алгоритма SCSU (Standard Compression Scheme for Unicode) - PowerPivot for Microsoft® Excel and Microsoft SharePoint Server (бывший codename “Gemini”) (загрузка пока не доступна, но обещается в скором времени) - Обновлённый Report Builder 3.0 - Master Data Services (бывший codename “Bulldog”) И улучшения августовского CTP: - Control Point Explorer в SQL Server Management Studio для централизованного управления и конроля распределения ресурсов серверов - Мастера, помогающие быстро настроить и подключить экземпляры SQL Server (Managed Instanses) и базы данных (Data-Tier Applications) к центральной системе управления - Индикаторы для контроля использования ресурсов серверами и базами данных - Ядро технологии StreamInsight (Complex Event Processing) Больше о нововведениях можно узнать на сайте продукта, и в соответствующем разделе MSDN. Ссылки по теме: - Домашняя страница SQL Server 2008 R2 - Загрузка SQL Server 2008 R2 November CTP - Раздел MSDN, посвящённый SQL Server 2008 R2 - Multi-Server Administration and Data-Tier Application - Master Data Services - PowerPivot for SharePoint - Анонс выхода CTP
|
-
Добрый день, хочу поделиться собственным опытом, и рассказать о том, чем я занимался всю прошлую неделю – искал и устранял причину, непонятно откуда взявшейся 605 ошибки. В понедельник, выйдя на работу, обнаружил в ящике кучу писем, с жалобами от клиентов, о том что на сайте не открываются те или иные страницы. Логи переполнены ошибками, и по ним видно, что проблема с базой. В логах сиквела светится куча 605 ошибок. Да уж, подумал я, теперь заказчик точно согласится, с тем, что нужно выделить время на оптимизацию базы (база нам досталась по наследству, и заказчик никак не хотел выделять время под оптимизацию). Сообщения об ошибках выглядели примерно так: Msg 605, Level 21, State 3, Line 2 Attempt to fetch logical page (3:85418) in database 7 failed. It belongs to allocation unit 4035234062485422080 not to 72057613478199296. Ошибки сыпались пачками. Сайт перестал нормально работать. Звонок заказчика “Сделай что-нибудь!!!”. Запускаю ALTER DATABASE my_db SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
DBCC CHECKDB (my_db, REPAIR_REBUILD)
GO
ALTER DATABASE my_db SET MULTI_USER
GO
всё работает. Проходит пару часов, та же проблема. Забыл сказать, DBCC CHECKDB ошибок не находит. Временная проблема? Я так не думаю.
Усиленно ищем решение. В том числе связываемся с админами и просим их проверить целостность диска (сервер развёрнут на виртуалке VMWare). Админы говорят, что не будут ничего делать, так как мы поудаляли их программы :) (ребята наставили на сервер с сиквелом кучу своих мониторилок и прочего ПО, которое отнимает ценные серверные ресурсы). Но всё же после разговора с заказчиком делают проверки и выносят вердикт: “дисковая подсистема полностью здорова”. Через несколько часов база падает опять. Поднимаем. К тому времени было выдвинуто несколько теорий возникновения ошибки. Проанализировали всё, что в последнее время изменилось (ничего глобального). Из причин того, что могло всё это вызвать, оставили только одно - рост нагрузки на сайт. Комплекс предпринятых мер:
- Останавливаем все компоненты и программы, которые могут влиять на производительность (CDC, планы обслужив-я, генератор фидов, пакеты SSIS, и т.д.)
- Пробегаем по запросам и убираем грязное чтение - http://support.microsoft.com/kb/235880
- Убираем из часто используемых и тяжёлых запросов использование временных таблиц и табличных переменных - http://support.microsoft.com/kb/960770 (+ качаем этот Хотфикс и планируем его установку на след утро, когда не будет нагрузки на сайт)
- Начинаем комплексную оптимизацию сайта (до этого заказчик не соглашался оплачивать оптимизацию как базы, так и сайта в целом)
При этом процессор и память используются по максимуму и 605 ошибки периодически начинают падать. Опция REPAIR_REBUILD не всегда помогает (в моём случае DBCC PAGE показывала, что повреждена страница данных, а не индексная), приходится запускать с опцией REPAIR_ALLOW_DATA_LOSS, которая помогает всегда. Но вот какая штука, REPAIR_ALLOW_DATA_LOSS должна удалять те страницы, которые нельзя восстановить, а COUNT(*) и до, и после восстановления возвращал одинаковое количество строк таблицы, т.е. сами данные не портятся. Причин этого я понять не мог.
На утро, со свежей головой, я накатил на сервер хотфикс, который, в теории, мог помочь. К тому времени, у меня родилась идея, того, что данные портятся не в таблице а в кэше, из-за большой нагрузки на сайт и нехватки ресурсов сервера. Но проверить я это не мог, пока не упала ошибка, а она упала, когда нагрузка на сайт возросла (хотфикс не помог). Как только это произошло, я почистил кэши:
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
И “О Чудо!”, сайт заработал :) Ещё пару раз проделывал этот трюк, чтобы проверить, что это не совпадение. Потом отписался заказчику по этому поводу и попросил ещё пару дней на оптимизацию, потому как чистка кэшей это не выход. Он согласился и попросил скрипт (чтобы не беспокоить нас ночью :) (разница во времени 7 часов)), который мы любезно ему предоставили. Ещё пару дней ушло на оптимизацию. В результате нагрузка на сервер снизилась почти вдвое, а ошибка 605 ушла, как и пришла. Для себя сделал вывод, что, всё же нужно донести до заказчика всю важность работ по опимизации, чтобы не допускать таких ситуаций. Надесь, мой опыт кому-то пригодится. Если кто-то сталкивался с подобной проблемой, пишите в комментах, как боролись.
Ссылки по теме:
- MSDN – Ошибка 605
- 605 ошибка – работа в временными таблицами
- 605 ошибка – грязное чтение
- Обсуждение ошибки на sql.ru
- Обсуждение ошибки на sqlservercentral.com
- DBCC CHECKDB
- DBCC PAGE
- DBCC FREEPROCCACHE
- DBCC DROPCLEANBUFFERS
|
-
|
|