MS SQL Server Кэширование запросов - PullRequest
0 голосов
/ 05 сентября 2018

Один из моих проектов имеет очень большую базу данных, в которой я не могу редактировать индексы и т. Д., Должен работать как есть.

При тестировании некоторых запросов, которые я буду выполнять в своей базе данных через службу, которую я пишу в .net, я видел, что они выполняются довольно медленно при первом запуске.

То, что они делали раньше, - это две основные (большие) таблицы, которые используются в основном. Они показали мне, что они открывают SQL Server Management Studio и запускают

SELECT * 
FROM table1 
JOIN table2

запрос, который запускается в первый раз около 5 минут, но затем занимает около 30 секунд, если вы запустите его снова, не закрывая SQL Server Management Studio. То, что они делают, они поддерживают SQL Server Management Studio открытой 24/7, поэтому, когда одна из их программ выполняет запросы, связанные с этими двумя таблицами (которые, по-видимому, являются почти всеми запросами, выполняемыми их программой), чтобы иметь 30 секунд время выполнения вместо 5 минут.

Это происходит потому, что я предполагаю, что 2 таблицы кэшируются, а затем нет (или почти нет) чтения с диска.

Является ли это хорошей идеей иметь службу, которая затем запускает запрос для кэширования этих 2 таблиц время от времени? Или есть лучшее решение для этого, учитывая тот факт, что я не могу редактировать индексы или разбивать таблицы и т. Д .?

Edit: Извините, но мне, возможно, было неясно, надеюсь, у базы данных уже есть индексы, просто мне не разрешено редактировать их или что-то в этом роде.

Редактировать 2: План запроса: https://www.brentozar.com/pastetheplan/?id=ByC5s06Dm

Ответы [ 4 ]

0 голосов
/ 07 сентября 2018

Спасибо обоим @scsimon @Branko Dimitrijevic за их ответы, я думаю, что они были действительно полезны и помогли мне в правильном направлении.

В итоге выясняется, что 2 самыми большими проблемами были аппаратные ресурсы (ОЗУ, отсутствие SSD) и функция автоматического закрытия, которая была установлена ​​в значение True.

Другие исправления, которые я сделал (пишу здесь для всех, кто пытается улучшить):

  • Вспомогательный сервисный инструмент будет реорганизовывать (дефрагментировать) индексы один раз каждые неделю и буду восстанавливать их раз в месяц.
  • Создайте представление, в котором есть все столбцы из двух рассматриваемых таблиц - чтобы исключить стоимость JOIN.
  • Посоветовал, что администратор базы данных, вероятно, поможет с лучшими таблицами / индексами
  • Рекомендуется улучшить аппаратное обеспечение сервера ...

Примет ответ @Branko Dimitrijevic, поскольку я не могу принять оба

0 голосов
/ 05 сентября 2018

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

0 голосов
/ 06 сентября 2018

Это может быть кандидат на индексированное представление (если вы можете убедить своего администратора баз данных создать его!), Что-то вроде:

CREATE VIEW transhead_transdata
WITH SCHEMABINDING
AS
    SELECT
        <columns of interest>
    FROM
        transhead th
        JOIN transdata td
            ON th.GID = td.HeadGID;

GO

CREATE UNIQUE CLUSTERED INDEX transjoined_uci ON transhead_transdata (<something unique>);

Это позволит «предварительно вычислить» JOIN (и синхронизировать его при изменении transhead и transdata).

0 голосов
/ 05 сентября 2018

Вы не можете создавать индексы? Это ваша самая большая проблема с производительностью. Лучшим решением было бы создать правильные индексы и учесть любую производительность, проверяя статистику ожидания, конкуренцию за ресурсы и т. Д. Я бы начал с блога Брента Озара и инструментов с открытым исходным кодом и двинулся вперед оттуда. .

Сохранение SSMS открытым не препятствует очистке кэша плана. Я бы начал с нескольких ссылок.

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

Можно сказать намного больше, но я остановлюсь здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...