Тормозит открытие счетов на детали Подчиненые документы

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

SELECT
   "ID",
   "InvoiceNumber",
   "CurrencyRate",
   "OwnerID",
   "OwnerName",
   "WorkflowItemID",
   "CustomerAccountTypeID"
FROM (
SELECT
   "tbl_Invoice"."ID" "ID",
   "tbl_Invoice"."InvoiceNumber" "InvoiceNumber",
   "tbl_Invoice"."CurrencyRate" "CurrencyRate",
   "tbl_Invoice"."OwnerID" "OwnerID",
   "Owner"."Name" "OwnerName",
   "tbl_Invoice"."WorkflowItemID" "WorkflowItemID",
   "Customer"."AccountTypeID" "CustomerAccountTypeID"
FROM
   "TS"."vw_Invoice" "tbl_Invoice"
LEFT OUTER JOIN
   "TS"."vw_Contact" "Owner" ON "Owner"."ID" = "tbl_Invoice"."OwnerID"
LEFT OUTER JOIN
   "TS"."vw_Account" "Customer" ON "Customer"."ID" = "tbl_Invoice"."CustomerID"
WHERE (NOT EXISTS
   (SELECT
      "tbl_DocumentInDocument"."ID" "ID"
   FROM
      "TS"."tbl_DocumentInDocument" "tbl_DocumentInDocument"
   WHERE ("tbl_DocumentInDocument"."ParentInvoiceID" = "tbl_Invoice"."ID" AND
      :pItemID IN ("tbl_DocumentInDocument"."ChildInvoiceID",
"tbl_DocumentInDocument"."ChildContractID",
"tbl_DocumentInDocument"."ChildDocumentID"))) AND
   NOT "tbl_Invoice"."ID" = :pNotID)
)
 WHERE ROWNUM = 40

и план его выполнения
Plan
SELECT STATEMENT  ALL_ROWSCost: 4,536  Bytes: 489  Cardinality: 1                                                                      
        26 COUNT STOPKEY                                                               
                25 NESTED LOOPS ANTI  Cost: 4,536  Bytes: 489  Cardinality: 1                                                  
                        22 NESTED LOOPS OUTER  Cost: 4,535  Bytes: 447  Cardinality: 1                                                 
                                14 NESTED LOOPS OUTER  Cost: 531  Bytes: 282  Cardinality: 1                                   
                                        6 HASH JOIN RIGHT SEMI  Cost: 390  Bytes: 223  Cardinality: 1                          
                                                4 VIEW VIEW SYS.VW_SQ_3 Cost: 196  Bytes: 47,565  Cardinality: 2,265                   
                                                        3 NESTED LOOPS SEMI  Cost: 196  Bytes: 280,860  Cardinality: 2,265             
                                                                1 TABLE ACCESS FULL TABLE TS.tbl_InvoiceRight Cost: 194  Bytes: 1,722,708  Cardinality: 22,086         
                                                                2 INDEX UNIQUE SCAN INDEX (UNIQUE) TS.PUserAdminUnit Cost: 0  Bytes: 46  Cardinality: 1        
                                                5 TABLE ACCESS FULL TABLE TS.tbl_Invoice Cost: 194  Bytes: 644,178  Cardinality: 6,378                         
                                        13 VIEW VIEW TS.vw_Account Cost: 140  Bytes: 59  Cardinality: 1                                
                                                12 HASH JOIN RIGHT SEMI  Cost: 140  Bytes: 104,814  Cardinality: 1,294                         
                                                        10 VIEW VIEW SYS.VW_SQ_1 Cost: 56  Bytes: 27,174  Cardinality: 1,294           
                                                                9 NESTED LOOPS SEMI  Cost: 56  Bytes: 160,456  Cardinality: 1,294      
                                                                        7 TABLE ACCESS FULL TABLE TS.tbl_AccountRight Cost: 55  Bytes: 908,232  Cardinality: 11,644  
                                                                        8 INDEX UNIQUE SCAN INDEX (UNIQUE) TS.PUserAdminUnit Cost: 0  Bytes: 46  Cardinality: 1  
                                                        11 TABLE ACCESS FULL TABLE TS.tbl_Account Cost: 83  Bytes: 196,080  Cardinality: 3,268                 
                                21 VIEW VIEW TS.vw_Contact Cost: 4,004  Bytes: 165  Cardinality: 1                                     
                                        20 HASH JOIN RIGHT SEMI  Cost: 4,004  Bytes: 2,178,169  Cardinality: 26,243                            
                                                18 VIEW VIEW SYS.VW_SQ_2 Cost: 1,112  Bytes: 551,103  Cardinality: 26,243                      
                                                        17 HASH JOIN RIGHT SEMI  Cost: 1,112  Bytes: 3,254,132  Cardinality: 26,243            
                                                                15 INDEX FAST FULL SCAN INDEX (UNIQUE) TS.PUserAdminUnit Cost: 3  Bytes: 138  Cardinality: 3   
                                                                16 TABLE ACCESS FULL TABLE TS.tbl_ContactRight Cost: 1,108  Bytes: 20,980,986  Cardinality: 268,987    
                                                19 TABLE ACCESS FULL TABLE TS.tbl_Contact Cost: 2,891  Bytes: 4,555,016  Cardinality: 73,468                   
                        24 TABLE ACCESS BY INDEX ROWID TABLE TS.tbl_DocumentInDocument Cost: 1  Bytes: 42  Cardinality: 1                                              
                                23 INDEX RANGE SCAN INDEX TS.IDocumentInDocParentInvoiceID Cost: 0  Cardinality: 1                                     

Что характерно в TOAD запрос так же выполняется медленно, а если убрать ограничение в 40 записей, то мгновенно. При добавлении в ту же деталь договоров или документов - список открывается быстро. Планы выполнения похожи.

Подскажите, пожалуйста, как устранить проблему.

Нравится

8 комментариев

Здравствуйте, Ozzy.
Вы правы, замедления связаны с тем, что пользователи работают через представления, соответсвенно выполняется множество проверок.
По вложенному плану выполнения видно, что наибольшее время занимает обращение к таблице контактов. Проверьте, какое количество записей содержится в таблице tbl_Contact. Какую версию Вы используете?

Наталия, в таблице tbl_Contact около 70 тыс записей. Версия 3.3.2.266, Оракл.

Ozzy, причина в контактах. Увеличить быстродействие можно убрав из запроса "OwnerName":

SELECT
   "ID",
   "InvoiceNumber",
   "CurrencyRate",
   "OwnerID",
   "WorkflowItemID",
   "CustomerAccountTypeID"
FROM (
SELECT 
   "tbl_Invoice"."ID" "ID",
   "tbl_Invoice"."InvoiceNumber" "InvoiceNumber",
   "tbl_Invoice"."CurrencyRate" "CurrencyRate",
   "tbl_Invoice"."OwnerID" "OwnerID",
   "tbl_Invoice"."WorkflowItemID" "WorkflowItemID",
   "Customer"."AccountTypeID" "CustomerAccountTypeID"
FROM 
   "TS"."vw_Invoice" "tbl_Invoice"
LEFT OUTER JOIN
   "TS"."vw_Account" "Customer" ON "Customer"."ID" = "tbl_Invoice"."CustomerID"
WHERE (NOT EXISTS 
   (SELECT 
      "tbl_DocumentInDocument"."ID" "ID"
   FROM 
      "TS"."tbl_DocumentInDocument" "tbl_DocumentInDocument"
   WHERE ("tbl_DocumentInDocument"."ParentInvoiceID" = "tbl_Invoice"."ID" AND
      :pItemID IN ("tbl_DocumentInDocument"."ChildInvoiceID", 
"tbl_DocumentInDocument"."ChildContractID", 
"tbl_DocumentInDocument"."ChildDocumentID"))) AND
   NOT "tbl_Invoice"."ID" = :pNotID)
)
 WHERE ROWNUM <= 40

Наталия, спасибо большое за подсказку. Теперь все стало работать быстрее. Хотя получилось немного кривоватое решение, потому что не видно ответственного по счету, ну да ладно. Странно вот только то, что при добавлении документа или договора такого торможения не наблюдается. И если с исходного запроса снять ограничение в 40 записей, то стоимость плана выполнения практически не изменяется, но запрос при этом возвращает результат мгновенно (312 мсек против 15 сек), хотя, судя по логике, как только появятся первые 40 записей запрос должен прервать свое выполнение и вернуть результат, соответственно его время выполнения должно быть до 1 сек, но никак не 15 сек. Вот эта проблема решаема?

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

Заметил, что в первоначальном запросе используется метод оптимизации ALL_ROWS. Явно указав в TOAD метод FIRST_ROWS достиг увеличения скорости выполнения раз в 10. Вопросы:

1. Можно ли в запросе Террасофт для данного запроса явно указать метод оптимизации?

2. Почему по умолчанию используется метод ALL_ROWS если многие запросы выполняются с ограничением в 40 записей?

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

Спасибо, Наталия! Всё получилось: вернул поле "OwnerName", добавил в запрос хинт FIRST_ROWS с помощью CustomSQLColumn и всё полетело.

Показать все комментарии