Истек тайм-аут выполнения представления SQL

#sql-server #query-optimization

#sql-сервер #оптимизация запросов

Вопрос:

У меня возникает проблема с таймаутом для моего представления. Но тайм-аут не является согласованным, это происходит только иногда.

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

ОШИБКА:

System.Data.SqlClient.SQLException (0x80131904): истек тайм-аут выполнения

Вот мое мнение:

 CREATE VIEW view_student 
AS     
    SELECT *      
    FROM Student p WITH (NOLOCK, FORCESEEK)      
    WHERE trantype = 23      
      AND NOT EXISTS (SELECT 't' FROM attachments m (nolock) 
                      WHERE m.tranid = p.tranid)          
      AND 1 = (CASE 
                  WHEN EXISTS (SELECT 'T' FROM person(NOLOCK) c      
                              WHERE c.type IN (32, 33))      
                       AND EXISTS (SELECT 'T' FROM contract(NOLOCK) co      
                                   WHERE co.TransactionNumber = p.tranid      
                                     AND RIGHT(co.FieldValue, 1) IN (3, 4, 5))      
                     THEN 0    
                     ELSE 1    
               END)    
  

Комментарии:

1. Представления не имеют тайм-аута, этот тайм-аут поступает из клиентского кода C #. Если вы берете код, который выполняет ваш клиент C #, и выполняете его в SSMS SET ARITHABORT ON , он плохо работает? Что говорит об этом фактический план выполнения? Я полагаю, вы увидите тысячи / миллионы отсчетов выполнения для каждого из ваших EXISTS(...) блоков, поэтому перестановка в код, чтобы быть умнее, вероятно, сделает его более производительным.

2. Прекратите разбрызгивать свой код с помощью nolock . Если вы должны его использовать, по КРАЙНЕЙ МЕРЕ, используйте текущий синтаксис, а не устаревший синтаксис. Не делайте больше работы!

3. SELECT 't' — Внутри предложения EXISTS содержимое строки не имеет значения, только наличие строки. И вы только добавляете путаницы, используя как прописные, так и строчные буквы. И, учитывая код и различные используемые имена, я предполагаю, что у вас могут возникнуть гораздо более серьезные проблемы с проектированием схемы.

4. @SMor это бизнес-требование, поэтому добавлен nolock. Спасибо за полезную ссылку о nolock.

5. @SMor, если я пропущу последнюю часть этого постоянного условия, то быстро просмотрю получение результата. Я не получил ни одного постоянного назначения, является причиной медлительности?

Ответ №1:

предложение для вас, пока вы не предоставите план запроса:

  1. если вы можете избавиться от nolock и других подсказок запроса, это не очень хорошая практика

  2. добавьте непостоянный вычисляемый столбец as RIGHT(co.FieldValue, 1) и создайте для него индекс.

  3. вы можете изменить свой запрос на приведенный ниже, чтобы немного упростить запрос, хотя это не является значительным улучшением производительности:

 CREATE VIEW view_student 
    AS     
        SELECT *      
        FROM Student p WITH (NOLOCK, FORCESEEK)      
        WHERE trantype = 23      
          AND NOT EXISTS (SELECT 't' FROM attachments m (nolock) 
                          WHERE m.tranid = p.tranid)          
          AND NOT EXISTS (SELECT 'T' FROM person(NOLOCK) c      
                                  WHERE c.type IN (32, 33))      
          AND NOT EXISTS (SELECT 'T' FROM contract(NOLOCK) co      
                                       WHERE co.TransactionNumber = p.tranid      
                                         AND RIGHT(co.FieldValue, 1) IN (3, 4, 5))
  

после просмотра плана запроса вот мой совет:

  1. Я вижу, что некоторые статистические данные отключены, и в результате план показывает, что у вас есть spill data , поэтому вам нужно поработать над ними, чтобы улучшить, это может быть просто решено путем обновления статистики для ваших таблиц, иначе вам нелегко дать вам ответ здесь. но попробуйте обновить свою статистику по всем таблицам.задействованные таблицы. UPDATE STATISTICS table_or_indexed_view_name
  2. также обновите статистику индекса, перестроив их, чтобы убедиться, что у вас лучшая статистика, вы можете перестроить их.

начните оттуда и снова вставьте сюда план

Комментарии:

1. также упростите запрос, если проблема заключается в представлении, просто выполните выбор только из представления без предложения where