Очень медленно загружается представление ... 
	  На страницу 1, 2  След. 
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Пн Мар 17, 2014 16:19   Очень медленно загружается представление ... | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Доброго времени суток, знатоки ЦФТ.
 
Мы никак не можем дружит с одной представлении оно у нас очень сильно тормозить (Банковский продукты -> Кредиты часным лицам -> "Список всех кредитов"). После анализа данной представлений выяснил что оно тормозит из-за этой связки:
 
'{'||(select case when count(1)>0 then '***' else '...' end from z#folder_pay fp where fp.c_prod_fold = to_char(a1_1.id))||'}' C_38
 
Оказывается у типе "Папки платежей" есть реквизит "PROD_FOLD" типа STRING_16(VARCHAR2(16)).
 
 
Никто не знает почему тип этого реквизита VARCHAR2 и как быть в данной ситуации?
 
 
Версия 6.0.115.53
 
Версия ТЯ 7.3.1.2
 
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
 
PL/SQL Release 11.2.0.4.0 - Production
 
CORE	11.2.0.4.0	Production
 
TNS for Linux: Version 11.2.0.4.0 - Production
 
NLSRTL Version 11.2.0.4.0 - Production | 
			 
		  | 
	 
	
		  | 
	 
	
		Random Эксперт
 
  Вступление в Клуб: 27.06.2011
  | 
		
			
				 Вт Мар 18, 2014 08:19   Re: Очень медленно загружается представление ... | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  После анализа данной представлений выяснил что оно тормозит из-за этой связки:
 
'{'||(select case when count(1)>0 then '***' else '...' end from z#folder_pay fp where fp.c_prod_fold = to_char(a1_1.id))||'}' C_38
 
Оказывается у типе "Папки платежей" есть реквизит "PROD_FOLD" типа STRING_16(VARCHAR2(16)).
 
 
Никто не знает почему тип этого реквизита VARCHAR2 и как быть в данной ситуации? | 	  
 
 
Тип напрягать не должен.
 
Попробуйте ограничить подсчёт данных. Ведь все данные, как я понял, в этом запросе нафик не нужны, нужно только знать, есть хоть одна запись, или нет.
 
 	  | Код: | 	 		  | (select case when count(1)>0 then '***' else '...' end from z#folder_pay fp where fp.c_prod_fold = to_char(a1_1.id) and rownum < 2) | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Вт Мар 18, 2014 13:31    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Поставил rownum < 2 не результат выполнения не изменилось.
 
А Вас join "where varchar = varchar" не смущает?
 
В таблице Z#PR_CRED около 69545 записи, в z#folder_pay 490478.
 
 
Ниже план запроса:
 
 	  | Код: | 	 		  SQL> explain plan for
 
  2  
 
  2  select (select case
 
  3                   when count(1) > 0 then
 
  4                    '***'
 
  5                   else
 
  6                    '...'
 
  7                 end
 
  8            from ibs.z#folder_pay fp
 
  9           where fp.c_prod_fold = to_char(a1_1.id)
 
 10             and rownum < 2) papka,a1_1.*
 
 11    from ibs.z#pr_cred a1_1;
 
Explained
 
 
SQL> select * from table(DBMS_XPLAN.DISPLAY);
 
PLAN_TABLE_OUTPUT
 
--------------------------------------------------------------------------------
 
Plan hash value: 769389634
 
--------------------------------------------------------------------------------
 
| Id  | Operation           | Name         | Rows  | Bytes | Cost (%CPU)| Time
 
--------------------------------------------------------------------------------
 
|   0 | SELECT STATEMENT    |              | 68481 |    19M|   899   (2)| 00:00:
 
|   1 |  SORT AGGREGATE     |              |     1 |     9 |            |
 
|*  2 |   COUNT STOPKEY     |              |       |       |            |
 
|*  3 |    TABLE ACCESS FULL| Z#FOLDER_PAY |     8 |    72 |  1275   (2)| 00:00:
 
|   4 |  TABLE ACCESS FULL  | Z#PR_CRED    | 68481 |    19M|   899   (2)| 00:00:
 
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
   2 - filter(ROWNUM<2)
 
   3 - filter("FP"."C_PROD_FOLD"=TO_CHAR(:B1))
 
17 rows selected | 	  
 
 
Можно использовать вместо "rownum < 2" хинт FIRST_ROWS но к сожалению время выполнения запроса не изменяется. 
 
 
 	  | Код: | 	 		  (select /*+FIRST_ROWS(1)*/case when count(1) > 0 then '***' else '...' end from ibs.z#folder_pay fp where fp.c_prod_fold = to_char(a1_1.id))
 
SQL> select * from table(DBMS_XPLAN.DISPLAY); 
 
PLAN_TABLE_OUTPUT
 
--------------------------------------------------------------------------------
 
Plan hash value: 3358409332
 
--------------------------------------------------------------------------------
 
| Id  | Operation          | Name         | Rows  | Bytes | Cost (%CPU)| Time
 
--------------------------------------------------------------------------------
 
|   0 | SELECT STATEMENT   |              |     1 |   301 |     2   (0)| 00:00:0
 
|   1 |  SORT AGGREGATE    |              |     1 |     9 |            |
 
|*  2 |   TABLE ACCESS FULL| Z#FOLDER_PAY |     8 |    72 |  1275   (2)| 00:00:1
 
|   3 |  TABLE ACCESS FULL | Z#PR_CRED    |     1 |   301 |     2   (0)| 00:00:0
 
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
   2 - filter("FP"."C_PROD_FOLD"=TO_CHAR(:B1))
 
15 rows selected
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		Alexsey Эксперт
 
  Вступление в Клуб: 06.09.2007
  | 
		
			
				 Вт Мар 18, 2014 15:09    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  Поставил rownum < 2 не результат выполнения не изменилось.
 
А Вас join "where varchar = varchar" не смущает?
 
В таблице Z#PR_CRED около 69545 записи, в z#folder_pay 490478.
 
 
Ниже план запроса:
 
 	  | Код: | 	 		  SQL> explain plan for
 
  2  
 
  2  select (select case
 
  3                   when count(1) > 0 then
 
  4                    '***'
 
  5                   else
 
  6                    '...'
 
  7                 end
 
  8            from ibs.z#folder_pay fp
 
  9           where fp.c_prod_fold = to_char(a1_1.id)
 
 10             and rownum < 2) papka,a1_1.*
 
 11    from ibs.z#pr_cred a1_1;
 
Explained
 
 
SQL> select * from table(DBMS_XPLAN.DISPLAY);
 
PLAN_TABLE_OUTPUT
 
--------------------------------------------------------------------------------
 
Plan hash value: 769389634
 
--------------------------------------------------------------------------------
 
| Id  | Operation           | Name         | Rows  | Bytes | Cost (%CPU)| Time
 
--------------------------------------------------------------------------------
 
|   0 | SELECT STATEMENT    |              | 68481 |    19M|   899   (2)| 00:00:
 
|   1 |  SORT AGGREGATE     |              |     1 |     9 |            |
 
|*  2 |   COUNT STOPKEY     |              |       |       |            |
 
|*  3 |   TABLE ACCESS FULL| Z#FOLDER_PAY |     8 |    72 |  1275   (2)| 00:00:
 
|   4 |  TABLE ACCESS FULL  | Z#PR_CRED    | 68481 |    19M|   899   (2)| 00:00:
 
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
   2 - filter(ROWNUM<2)
 
   3 - filter("FP"."C_PROD_FOLD"=TO_CHAR(:B1))
 
17 rows selected | 	  
 
 
Можно использовать вместо "rownum < 2" хинт FIRST_ROWS но к сожалению время выполнения запроса не изменяется. 
 
 
 	  | Код: | 	 		  (select /*+FIRST_ROWS(1)*/case when count(1) > 0 then '***' else '...' end from ibs.z#folder_pay fp where fp.c_prod_fold = to_char(a1_1.id))
 
SQL> select * from table(DBMS_XPLAN.DISPLAY); 
 
PLAN_TABLE_OUTPUT
 
--------------------------------------------------------------------------------
 
Plan hash value: 3358409332
 
--------------------------------------------------------------------------------
 
| Id  | Operation          | Name         | Rows  | Bytes | Cost (%CPU)| Time
 
--------------------------------------------------------------------------------
 
|   0 | SELECT STATEMENT   |              |     1 |   301 |     2   (0)| 00:00:0
 
|   1 |  SORT AGGREGATE    |              |     1 |     9 |            |
 
|*  2 |   TABLE ACCESS FULL| Z#FOLDER_PAY |     8 |    72 |  1275   (2)| 00:00:1
 
|   3 |  TABLE ACCESS FULL | Z#PR_CRED    |     1 |   301 |     2   (0)| 00:00:0
 
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
   2 - filter("FP"."C_PROD_FOLD"=TO_CHAR(:B1))
 
15 rows selected
 
 | 	 
  | 	  
 
 
Странно
 
у меня запрос, приведенный Вами, отрабатывает 4 секунды и отбирает более 300 000 кредитов. Да, кстати, я бы посмотрел почему у вас на индекс не встал запрос по FOLDER_PAY?
 
 	  | Цитата: | 	 		  Plan hash value: 1257241260
 
 
 
-------------------------------------------------------------------------------------------------------------------
 
| Id   | Operation                  | Name                                | Rows  | Bytes | Cost (%CPU)| Time     |
 
--------------------------------------------------------------------------------------------------------------------
 
|   0  | SELECT STATEMENT   |                                          |   430K|   143M|  7234  (52)| 00:00:02 |
 
|   1  |  SORT AGGREGATE    |                                          |     1    |    11   |                 |               |
 
|*  2 |   COUNT STOPKEY      |                                          |           |          |                 |                |
 
|*  3 |    INDEX RANGE SCAN| IDX_Z#FOLDER_PAY_PROD |    26    |   286  |     1   (0)   | 00:00:01 |
 
|   4  |  TABLE ACCESS FULL  | Z#PR_CRED                       |   430K|   143M|  7234  (52)| 00:00:02 |
 
--------------------------------------------------------------------------------------------
 
 
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
 
 
   2 - filter(ROWNUM<2)
 
   3 - access("FP"."C_PROD_FOLD"=TO_CHAR(:B1)) | 	 
  _________________ всегда есть как минимум 2 выхода | 
			 
		  | 
	 
	
		  | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Вт Мар 18, 2014 15:29    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				| Alexsey, у Вас по реквизиту "C_PROD_FOLD" есть индексы? | 
			 
		  | 
	 
	
		  | 
	 
	
		Alexsey Эксперт
 
  Вступление в Клуб: 06.09.2007
  | 
		
			
				 Вт Мар 18, 2014 15:35    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  | Alexsey, у Вас по реквизиту "C_PROD_FOLD" есть индексы? | 	  
 
Есть. _________________ всегда есть как минимум 2 выхода | 
			 
		  | 
	 
	
		  | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Вт Мар 18, 2014 15:41    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Alexsey пишет: | 	 		   	  | Sant пишет: | 	 		  | Alexsey, у Вас по реквизиту "C_PROD_FOLD" есть индексы? | 	  
 
Есть. | 	  
 
Вы сами создали индекс?
 
Версия ТЯ какая у Вас? | 
			 
		  | 
	 
	
		  | 
	 
	
		Alexsey Эксперт
 
  Вступление в Клуб: 06.09.2007
  | 
		
			
				 Вт Мар 18, 2014 15:58    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		   	  | Alexsey пишет: | 	 		   	  | Sant пишет: | 	 		  | Alexsey, у Вас по реквизиту "C_PROD_FOLD" есть индексы? | 	  
 
Есть. | 	  
 
Вы сами создали индекс?
 
Версия ТЯ какая у Вас? | 	  
 
ТЯ 7.3.7.0
 
версия 14.1
 
Не помню чтобы, мы сами этот индекс создавали. Скорее всего дистрибутивный. _________________ всегда есть как минимум 2 выхода | 
			 
		  | 
	 
	
		  | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Вт Мар 18, 2014 16:32    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Понятно, а можно что нибудь делать в данной ситуации? или кроме ЦФТ никто не может помочь?
 
Еще такой вопрос почему у реквизита "C_PROD_FOLD" тип varchar а не number ? | 
			 
		  | 
	 
	
		  | 
	 
	
		Alexsey Эксперт
 
  Вступление в Клуб: 06.09.2007
  | 
		
			
				 Вт Мар 18, 2014 20:29    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  Понятно, а можно что нибудь делать в данной ситуации? или кроме ЦФТ никто не может помочь?
 
Еще такой вопрос почему у реквизита "C_PROD_FOLD" тип varchar а не number ? | 	  
 
Для начала связаться с ЦФТ и уточнить у них про индекс. Как вариант индекс можно создать самим. 
 
Вы сами решите нужно вам быстрое представление быстрое и дистрибутивное или вы будите его делать локально. _________________ всегда есть как минимум 2 выхода | 
			 
		  | 
	 
	
		  | 
	 
	
		Random Эксперт
 
  Вступление в Клуб: 27.06.2011
  | 
		
			
				 Ср Мар 19, 2014 07:04    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  Поставил rownum < 2 не результат выполнения не изменилось.
 
А Вас join "where varchar = varchar" не смущает? | 	  
 
А почему он меня должен смущать? Чем varchar2 такой особенный, что он меня смущать должен?
 
 
number = varchar2 или varchar2 = number меня бы смутил, так как тут возможно неявное преобразование типов, что ведёт к слетанию с индекса.
 
 
 	  | Sant пишет: | 	 		  
 
В таблице Z#PR_CRED около 69545 записи, в z#folder_pay 490478.
 
 
Ниже план запроса:
 
 	  | Код: | 	 		  SQL> explain plan for
 
  2  
 
  2  select (select case
 
  3                   when count(1) > 0 then
 
  4                    '***'
 
  5                   else
 
  6                    '...'
 
  7                 end
 
  8            from ibs.z#folder_pay fp
 
  9           where fp.c_prod_fold = to_char(a1_1.id)
 
 10             and rownum < 2) papka,a1_1.*
 
 11    from ibs.z#pr_cred a1_1;
 
Explained
 
 
SQL> select * from table(DBMS_XPLAN.DISPLAY);
 
PLAN_TABLE_OUTPUT
 
--------------------------------------------------------------------------------
 
Plan hash value: 769389634
 
--------------------------------------------------------------------------------
 
| Id  | Operation           | Name         | Rows  | Bytes | Cost (%CPU)| Time
 
--------------------------------------------------------------------------------
 
|   0 | SELECT STATEMENT    |              | 68481 |    19M|   899   (2)| 00:00:
 
|   1 |  SORT AGGREGATE     |              |     1 |     9 |            |
 
|*  2 |   COUNT STOPKEY     |              |       |       |            |
 
|*  3 |    TABLE ACCESS FULL| Z#FOLDER_PAY |     8 |    72 |  1275   (2)| 00:00:
 
|   4 |  TABLE ACCESS FULL  | Z#PR_CRED    | 68481 |    19M|   899   (2)| 00:00:
 
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
 
---------------------------------------------------
 
   2 - filter(ROWNUM<2)
 
   3 - filter("FP"."C_PROD_FOLD"=TO_CHAR(:B1))
 
17 rows selected | 	  
 
 | 	  
 
План, конечно, безобразный. Как сказал Alexsey, нужен индекс по полю C_PROD_FOLD.
 
Есть дистрибутивный индекс IDX FOLDER_PAY IDX_Z#FOLDER_PAY_PROD, заведён с версии 8.7. Если у вас в метаданных он есть, а на схеме нет, обратитесь к вашим ДБА, а если нет и в метаданных, то к службе поддержки ЦФТ.
 
 
 	  | Sant пишет: | 	 		  | Можно использовать вместо "rownum < 2" хинт FIRST_ROWS но к сожалению время выполнения запроса не изменяется.  | 	  
 
Вы считаете правильным применять хинт, оптимизирующий план запроса для получения первой записи, когда в запросе подсчитываются все записи? Запрос-то от хинта не изменится. Вы считаете такую замену равнозначной?
  Последний раз редактировалось: Random (Ср Мар 19, 2014 07:14), всего редактировалось 1 раз | 
			 
		  | 
	 
	
		  | 
	 
	
		Random Эксперт
 
  Вступление в Клуб: 27.06.2011
  | 
		
			
				 Ср Мар 19, 2014 07:11    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Sant пишет: | 	 		  Понятно, а можно что нибудь делать в данной ситуации? или кроме ЦФТ никто не может помочь?
 
Еще такой вопрос почему у реквизита "C_PROD_FOLD" тип varchar а не number ? | 	  
 
 
Видимо, для того, чтобы не создавался foreign key и не мешался. Возможно, в этом поле не только числовые идентификаторы хранятся.
 
Мало ли для чего разработчик задумал это поле.
 
 
Что вас смущает, я не пойму? | 
			 
		  | 
	 
	
		  | 
	 
	
		Alkov Профи
 
  Вступление в Клуб: 23.09.2010
  | 
		
			
				 Ср Мар 19, 2014 09:56    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Цитата: | 	 		  | select case when count(1)>0 then '***' else | 	  
 
imho правильней не count(1) , а count(id)
 
 
p.s. Почему FULLSCAN то по таблице, ,будет индекс - будет скорость | 
			 
		  | 
	 
	
		  | 
	 
	
		Sant Участник со стажем
 
  Вступление в Клуб: 19.08.2013
  | 
		
			
				 Ср Мар 19, 2014 13:08    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Random пишет: | 	 		  
 
А почему он меня должен смущать? Чем varchar2 такой особенный, что он меня смущать должен?
 
number = varchar2 или varchar2 = number меня бы смутил, так как тут возможно неявное преобразование типов, что ведёт к слетанию с индекса.
 
 | 	  
 
Да, в принципе я с Вами согласен.
 
 
 	  | Random пишет: | 	 		  
 
План, конечно, безобразный. Как сказал Alexsey, нужен индекс по полю C_PROD_FOLD.
 
Есть дистрибутивный индекс IDX FOLDER_PAY IDX_Z#FOLDER_PAY_PROD, заведён с версии 8.7. Если у вас в метаданных он есть, а на схеме нет, обратитесь к вашим ДБА, а если нет и в метаданных, то к службе поддержки ЦФТ.
 
 | 	  
 
Нет, в метаданных не нашли, попробуем написать в службу поддержки ЦФТ.
 
 
 	  | Random пишет: | 	 		  
 
Вы считаете правильным применять хинт, оптимизирующий план запроса для получения первой записи, когда в запросе подсчитываются все записи? Запрос-то от хинта не изменится. Вы считаете такую замену равнозначной?
 
 | 	  
 
Нет, так не считаю и в нашем запросе  хинт FIRST_ROWS и rownum<2 не равнозначны.
 
 	  | Random пишет: | 	 		  
 
Видимо, для того, чтобы не создавался foreign key и не мешался. Возможно, в этом поле не только числовые идентификаторы хранятся. 
 
Мало ли для чего разработчик задумал это поле. 
 
Что вас смущает, я не пойму?
 
 | 	  
 
Думаю нашу проблему бы решил простой добавлении индекса, но меня не понятно почему разработчики не добавили индекс в ранних версиях, в потом добавили скорее все это их ошибка. | 
			 
		  | 
	 
	
		  | 
	 
	
		Random Эксперт
 
  Вступление в Клуб: 27.06.2011
  | 
		
			
				 Ср Мар 19, 2014 13:57    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				 	  | Alkov пишет: | 	 		   	  | Цитата: | 	 		  | select case when count(1)>0 then '***' else | 	  
 
imho правильней не count(1) , а count(id)
 
 
p.s. Почему FULLSCAN то по таблице, ,будет индекс - будет скорость | 	  
 
 
  count почти по барабану по чему делать. Просто указать 1 во-первых, короче, во-вторых, никак не связано с запросом.
 
 
в pl/+ писать count(*) не получится, писать count(a%id) - нужно помнить об этом a, и если меняешь алиас, нужно менять его и в скобках count. Короче, имхо, для целей разработки, удобнее использовать константу.
 
 
И ещё. Попробуй посмотреть и сравнить планы запросов:
 
 	  | Код: | 	 		  
 
select count(1) from z#ac_fin where c_main_v_id like '%'
 
select count(distinct c_main_v_id) from z#ac_fin where c_main_v_id like '%'
 
select count(distinct id) from z#ac_fin where c_main_v_id like '%'
 
 | 	 
 
  Последний раз редактировалось: Random (Ср Мар 19, 2014 14:36), всего редактировалось 3 раз(а) | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |