Решение проблем DotNetNuke при работе с БД

Материал из 1GbWiki.

(Различия между версиями)
Перейти к: навигация, поиск
Версия 16:14, 5 декабря 2008 (править)
Dmach (Обсуждение | вклад)
(Новая: == Отключение логов == DotNetNuke (далее DNN) по умолчанию ведёт несколько логов своей деятельности в БД: * SiteLo...)
← К предыдущему изменению
Текущая версия (14:42, 24 марта 2010) (править) (отменить)
Rin (Обсуждение | вклад)
м
 
(14 промежуточных версий не показаны.)
Строка 10: Строка 10:
* Дополнительные расходы на запись данных в эти таблицы * Дополнительные расходы на запись данных в эти таблицы
* Резко увеличивается размер БД, таблица SiteLog может содержать миллионы записей * Резко увеличивается размер БД, таблица SiteLog может содержать миллионы записей
 +* Таблицы практически без индексов, построение отчёта по ним приведёт к пробемам
* Методы очистки этих таблиц при своём исполнении потребляют крайне много ресурсов * Методы очистки этих таблиц при своём исполнении потребляют крайне много ресурсов
-Также отметим, что в этих таблицах нет прямой необходимости. Статистика посещений сайта также доступна со стороны хостинга, посмотрите статью по [http://www.1gb.ru/logs статистике]. Таблица ошибок не нужна, если ваш сайт работает исправно и не требует отладки или вмешательства программистов. +Также отметим, что в этих таблицах нет прямой необходимости. Статистика посещений сайта также доступна со стороны хостинга, посмотрите статью по [http://www.1gb.ua/logs статистике]. Таблица ошибок не нужна, если ваш сайт работает исправно и не требует отладки или вмешательства программистов.
-Против ведения таблицы SiteLog выступает и [http://www.1gb.ru/regl регламент хостинга], пункт 2.5.b как раз про это.+Против ведения таблицы SiteLog выступает и [http://www.1gb.ua/regl регламент хостинга], пункт 2.5.b как раз про это.
-=== Как отключить? ===+=== Отключение SiteLog ===
-К сожалению, мы не знаем. Обратитесь к документации по DNN. Если штатными средствами этого сделать нельзя – вам следует найти в коде DNN место ведения этих логов и в методе (функции), где исполняется INSERT-запрос на добавление данных – убрать его.+* Авторизуемся как Host
 +* Заходим ''Host'' → ''Portals''
 +* Для каждого сайта, входящего в Ваш портал, изменяем параметры («карандаш» рядом с названием сайта)
 +* Нам нужен раздел ''Дополнительные параметры'' → ''Параметры хоста'' → ''Хранение журнала'', обнуляем значение, т.е. ставим в поле ''Хранение журнала'' "0" (без кавычек)
 +* Сохраняем изменения
После отключения логов вам необходимо очистить таблицы от имеющихся в них данных. Не вздумайте исполнять запрос типа '''DELETE FROM SiteLog''' – в условиях удаления миллионов строк это создаст массу проблем, так как для каждой операции удаления строки будет создана запись в логе транзакций. Используйте метод очистки таблиц MSSQL без ведения лога транзакций – [http://technet.microsoft.com/ru-ru/library/ms177570.aspx TRUNCATE TABLE], например: После отключения логов вам необходимо очистить таблицы от имеющихся в них данных. Не вздумайте исполнять запрос типа '''DELETE FROM SiteLog''' – в условиях удаления миллионов строк это создаст массу проблем, так как для каждой операции удаления строки будет создана запись в логе транзакций. Используйте метод очистки таблиц MSSQL без ведения лога транзакций – [http://technet.microsoft.com/ru-ru/library/ms177570.aspx TRUNCATE TABLE], например:
Строка 25: Строка 30:
Запрос исполняется мгновенно и не вызывает проблем перегрузки. Запрос исполняется мгновенно и не вызывает проблем перегрузки.
 +
 +=== Отключение EventLog ===
 +
 +* Авторизуемся как Host
 +* Заходим ''Admin (Администратор)'' → ''Event Viewer (Просмотр журнала)''
 +** '''Важно:''' если вы не можете войти в этот раздел из-за большого числа записей в EventLog - удалите имещиеся записи в таблице методом ''TRUNCATE TABLE'' '''до''' отключения ведения журнала
 +* Внизу, под таблицей, нажимаем ''Edit Log Settings (Параметры журнала)''
 +* Появляется список событий, которые фиксируются в EventLog
 +* Последовательно заходим в каждое, которое разрешено (True), и отключаем ''Logging Enabled (Сохранять события)''
 +* Сохраняем изменения
 +
 +После того, как в списке не остаётся ни одного события True, нажимаем Возврат, возвращаемся на входную страницу прсмотра журнала. Внизу списка появляется ''Очистить журнал (Clear Event Log)'' - пользоваться этой функцией не надо, смотрите выше пример использования '''TRUNCATE TABLE'''.
 +
 +== Хранимая процедура Forum_ISearchable ==
 +
 +'''Внимание!''' Это решение зависит от версии DNN и может не дать эффекта. Проверяйте результат.
 +
 +Суть проблемы в том, что внутри этой процедуры исполняется SELECT с двумя параметрами по множеству связанных таблиц. При это для таблиц проставлены внешние ключи и, предпологается, что это должно решить проблему. Однако это не так. Внутренний запрос примерно выглядит так (лишние поля убраны для ясности):
 +
 + SELECT P.[ThreadID],
 + P.[PostID],
 + ...
 + P.[DateApproved],
 + F.PublicView
 + FROM dbo.Forum_Posts P
 + INNER JOIN dbo.Forum_Threads T ON P.ThreadID = T.ThreadID
 + INNER JOIN dbo.Forum_Forums F ON T.ForumID = F.ForumID
 + INNER JOIN dbo.Forum_Groups G ON F.GroupID = G.GroupID
 + WHERE G.ModuleID = 123
 + AND P.[CreatedDate] >= '2008-12-05 16:41:39:467'
 +
 +Для всех полей из FROM объединённых через INNER JOIN стоят внешние ключи. По полю Forum_Groups.ModuleID также есть индекс. По полю Forum_Posts.CreatedDate индекса нет (!). Казалось бы - достаточно создать индекс по полю CreatedDate для эффективной выборки по нему. К сожалению это не действует, так как основным индексом в данном случае SQL Server выбирает внешний ключ по полю Forum_Posts.ThreadID. Решение - создать внутренний (обычный) индекс по полю Forum_Posts.ThreadID и сделать его составным добавив вторым полем в индексе Forum_Posts.CreatedDate - в этом случае новый индекс сможет успешно заменить собой внешний ключ и SQL Server сможет использовать индекс пополю Forum_Posts.CreatedDate. Ниже код создания индекса:
 +
 + CREATE NONCLUSTERED INDEX [IX_ThreadID_CreatedDate] ON [dbo].[Forum_Posts]
 + (
 + [ThreadID] ASC,
 + [CreatedDate] ASC
 + )
 + WITH (
 + PAD_INDEX = OFF,
 + STATISTICS_NORECOMPUTE = OFF,
 + SORT_IN_TEMPDB = OFF,
 + IGNORE_DUP_KEY = OFF,
 + DROP_EXISTING = OFF,
 + ONLINE = OFF,
 + ALLOW_ROW_LOCKS = ON,
 + ALLOW_PAGE_LOCKS = ON
 + ) ON [PRIMARY]
 +
 +После этого потребление ресурсов на исполнение запроса снижается в 30 раз (на тестируемом DNN).
== Напишите нам == == Напишите нам ==
Строка 32: Строка 87:
== Ссылки по теме == == Ссылки по теме ==
-[[Решение проблем с запросами в Microsoft SQL Server]]+* [[Решение проблем с запросами в Microsoft SQL Server]]
 +* [http://www.dotnetnuke.com/ Официальный сайт DotNetNuke]
[[Категория:Серверная нагрузка]] [[Категория:Серверная нагрузка]]
-[[Категория:MSSQL]]+[[Категория:MS-SQL]]

Текущая версия

Содержание

[править] Отключение логов

DotNetNuke (далее DNN) по умолчанию ведёт несколько логов своей деятельности в БД:

  • SiteLog – статистика запросов к сайту, прямой аналог логов веб-сервера без учёта запросов к статическим файлам
  • EventLog – лог внутренних событий DNN, например - ошибок

К сожалению, это всё не проходит бесследно. Из негативных моментов такой работы следует отметить:

  • Дополнительные расходы на запись данных в эти таблицы
  • Резко увеличивается размер БД, таблица SiteLog может содержать миллионы записей
  • Таблицы практически без индексов, построение отчёта по ним приведёт к пробемам
  • Методы очистки этих таблиц при своём исполнении потребляют крайне много ресурсов

Также отметим, что в этих таблицах нет прямой необходимости. Статистика посещений сайта также доступна со стороны хостинга, посмотрите статью по статистике. Таблица ошибок не нужна, если ваш сайт работает исправно и не требует отладки или вмешательства программистов.

Против ведения таблицы SiteLog выступает и регламент хостинга, пункт 2.5.b как раз про это.

[править] Отключение SiteLog

  • Авторизуемся как Host
  • Заходим HostPortals
  • Для каждого сайта, входящего в Ваш портал, изменяем параметры («карандаш» рядом с названием сайта)
  • Нам нужен раздел Дополнительные параметрыПараметры хостаХранение журнала, обнуляем значение, т.е. ставим в поле Хранение журнала "0" (без кавычек)
  • Сохраняем изменения

После отключения логов вам необходимо очистить таблицы от имеющихся в них данных. Не вздумайте исполнять запрос типа DELETE FROM SiteLog – в условиях удаления миллионов строк это создаст массу проблем, так как для каждой операции удаления строки будет создана запись в логе транзакций. Используйте метод очистки таблиц MSSQL без ведения лога транзакций – TRUNCATE TABLE, например:

TRUNCATE TABLE SiteLog

Запрос исполняется мгновенно и не вызывает проблем перегрузки.

[править] Отключение EventLog

  • Авторизуемся как Host
  • Заходим Admin (Администратор)Event Viewer (Просмотр журнала)
    • Важно: если вы не можете войти в этот раздел из-за большого числа записей в EventLog - удалите имещиеся записи в таблице методом TRUNCATE TABLE до отключения ведения журнала
  • Внизу, под таблицей, нажимаем Edit Log Settings (Параметры журнала)
  • Появляется список событий, которые фиксируются в EventLog
  • Последовательно заходим в каждое, которое разрешено (True), и отключаем Logging Enabled (Сохранять события)
  • Сохраняем изменения

После того, как в списке не остаётся ни одного события True, нажимаем Возврат, возвращаемся на входную страницу прсмотра журнала. Внизу списка появляется Очистить журнал (Clear Event Log) - пользоваться этой функцией не надо, смотрите выше пример использования TRUNCATE TABLE.

[править] Хранимая процедура Forum_ISearchable

Внимание! Это решение зависит от версии DNN и может не дать эффекта. Проверяйте результат.

Суть проблемы в том, что внутри этой процедуры исполняется SELECT с двумя параметрами по множеству связанных таблиц. При это для таблиц проставлены внешние ключи и, предпологается, что это должно решить проблему. Однако это не так. Внутренний запрос примерно выглядит так (лишние поля убраны для ясности):

SELECT  P.[ThreadID],
        P.[PostID],
        ...
        P.[DateApproved],
        F.PublicView
FROM    dbo.Forum_Posts P
        INNER JOIN dbo.Forum_Threads T ON P.ThreadID = T.ThreadID
        INNER JOIN dbo.Forum_Forums F ON T.ForumID = F.ForumID
        INNER JOIN dbo.Forum_Groups G ON F.GroupID = G.GroupID
WHERE   G.ModuleID = 123
        AND P.[CreatedDate] >= '2008-12-05 16:41:39:467'

Для всех полей из FROM объединённых через INNER JOIN стоят внешние ключи. По полю Forum_Groups.ModuleID также есть индекс. По полю Forum_Posts.CreatedDate индекса нет (!). Казалось бы - достаточно создать индекс по полю CreatedDate для эффективной выборки по нему. К сожалению это не действует, так как основным индексом в данном случае SQL Server выбирает внешний ключ по полю Forum_Posts.ThreadID. Решение - создать внутренний (обычный) индекс по полю Forum_Posts.ThreadID и сделать его составным добавив вторым полем в индексе Forum_Posts.CreatedDate - в этом случае новый индекс сможет успешно заменить собой внешний ключ и SQL Server сможет использовать индекс пополю Forum_Posts.CreatedDate. Ниже код создания индекса:

CREATE NONCLUSTERED INDEX [IX_ThreadID_CreatedDate] ON [dbo].[Forum_Posts] 
(
    [ThreadID] ASC,
    [CreatedDate] ASC
)
WITH (
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    SORT_IN_TEMPDB = OFF, 
    IGNORE_DUP_KEY = OFF,  
    DROP_EXISTING = OFF, 
    ONLINE = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON
) ON [PRIMARY]

После этого потребление ресурсов на исполнение запроса снижается в 30 раз (на тестируемом DNN).

[править] Напишите нам

Если вы уже занимались проблемой оптимизации работы DNN с базой данных и выполняли действия из этой статьи или действия другого типа – напишите нам или прямо сюда сценарий решения проблем. Это поможет множеству людей и увеличит сумму счастья на планете.

[править] Ссылки по теме

Личные инструменты