Никто не сталкивался с такой проблемой: при нажатии кнопки Добавить Счет в детали Подчиненные документы раздела Документы очень долго (больше 20 сек) не открывается список счетов. Происходит это для всех пользователей, кроме администратора. Думаю связано это с тем, что пользователи к этой таблице обращаются через представление. Появилось это недавно. Доработок этих разделов никаких не было. БД Оракл. Анализ таблиц сделал. Прикладываю сам запрос
"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
и план его выполнения
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 записей, то мгновенно. При добавлении в ту же деталь договоров или документов - список открывается быстро. Планы выполнения похожи.
Подскажите, пожалуйста, как устранить проблему.
Нравится
Здравствуйте, Ozzy.
Вы правы, замедления связаны с тем, что пользователи работают через представления, соответсвенно выполняется множество проверок.
По вложенному плану выполнения видно, что наибольшее время занимает обращение к таблице контактов. Проверьте, какое количество записей содержится в таблице tbl_Contact. Какую версию Вы используете?
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 запланирован анализ и переработка страничной выборки записей и выбор данных под пользователем.