Хочу научиться читать SQL...

zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Хочу научиться читать SQL...

Post by zVlad »

Эта тема специально для iDesperedo. Не хочу превращать деловую тему в помойку перетягивания каната в области "умения читать SQL".

Вот простенький SQL (у мeня их несколько от последней миграции, так что не соскучимся) который мы совсем недавно выявили и попросили обратиьть на него внимание разработчиков. Прочитайте и Вы, iDesperado, этот SQL с умением и рассказы что было в нем не так и что разработчики в итоге сдеали с ним. Спасибо.

Code: Select all

SELECT WOTSK.FACILITY , WOTSK.UNIT , WOTSK.INTERRUPT
       , WOTSK.SHUTDOWN_NBR , WOTSK.WORK_ORDER_NBR
       , WOTSK.WORK_ORDER_TASK , WOTSK.TASK_SEQUENCE
       , WOTSK.WO_TSK_STATUS
       , WOTSK.WO_TSK_PRIORITY
       , WOTSK.NEED_DATE , WOTSK.WR_TASK_TITLE
 FROM AS07DADM.TIDWOTSK WOTSK
 WHERE ( WOTSK.WORK_ORDER_NBR BETWEEN ? AND ? )
 AND ( EXISTS ( SELECT 1 FROM AS07DADM.TIDWOTSK WOTS1
      WHERE ( WOTS1.WORK_ORDER_NBR = WOTSK.WORK_ORDER_NBR )
       AND ( WOTS1.WORK_ORDER_TASK = WOTSK.WORK_ORDER_TASK )
     AND ( ( WOTS1.FACILITY = ? ) OR ( 1 = 0 ) )
     AND ( ( WOTS1 .UNIT BETWEEN ? AND ? ) OR ( 1 = 0 ) )
      AND ( ( WOTS1.WO_TSK_STATUS    = '45' )
             OR ( WOTS1.WO_TSK_STATUS = '48' ) )
         ) OR ( 1 = 0 )
           )
      AND ( ( WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK
           BETWEEN ?  AND ?  ) OR ( 1 = 0 ) )
ORDER BY WOTSK.WORK_ORDER_NBR DESC
      , WOTSK.WORK_ORDER_TASK DESC;
Индексы (я их не для того привожу что хочу узнать от Вас какие именно индексы используются. Более того они и не рассматривались когда делались рекомендации. Просто предваряя возможный интерес к ним привожу):

Code: Select all

  CREATE UNIQUE INDEX TIIWOTSK ON TIDWOTSK
      (
         WORK_ORDER_NBR DESC,                                             0533
         WORK_ORDER_TASK DESC                                             0299
      )
....
  CREATE UNIQUE INDEX TIIWOTS1 ON TIDWOTSK
      (
         FACILITY,                                                        0533
         UNIT,                                                            0533
         SYSTEM_CODE,                                                     0533
         EQUIPMENT_TYPE,                                                  0533
         EQUIPMENT_NUMBER,                                                0533
         DISCIPLINE,                                                      0533
         WORK_ORDER_NBR,                                                  0533
         WORK_ORDER_TASK,                                                 0533
         WO_TSK_STATUS                                                    0533
      )
...
  CREATE        INDEX TIIWOTS2 ON TIDWOTSK
      (
         UTC_NUMBER
      )
....
  CREATE        INDEX TIIWOTS3 ON TIDWOTSK
      (
         E_CODE,
         WORK_ORDER_NBR,
         WO_TSK_STATUS                                                    0533
      )
...
   CREATE      INDEX TIIWOTS4 ON TIDWOTSK
      (
         WORK_ORDER_NBR,
         WORK_ORDER_TASK,                                                 0533
         WO_TSK_STATUS,
         NEED_DATE,
         WORK_ORDER_TYPE,
         UNIT,                                                            0533
         SYSTEM_CODE,                                                     0533
         DISCIPLINE,
         WO_TSK_PRIORITY
      )
....
   CREATE UNIQUE INDEX TIIWOTS5 ON TIDWOTSK
      (
         KEY_REF_NBR,
         KEY_REF_SUB_NBR,
         KEY_REF_TYPE
      )
...
  CREATE        INDEX TIIWOTS6 ON TIDWOTSK
      (
       LOCATION_ID,
       LOCATION_REGION,
       WORK_ORDER_NBR
      )
....
  CREATE        INDEX TIIWOTS7 ON TIDWOTSK
      (
       REFERENCE_TYPE,
       REFERENCE_NBR
      )
...
  CREATE UNIQUE INDEX TIIWOTS9 ON TIDWOTSK
      (
         FACILITY,
         WORK_ORDER_NBR,
         WORK_ORDER_TASK
      )
.....
  CREATE        INDEX TIIWOTSA ON TIDWOTSK
      (
       CLIENT_ID
      )
..............
  CREATE        INDEX TIIWOTSB ON TIDWOTSK
      (
         CATALOG_ID,
         Q_LEVEL,
         FACILITY
      )

iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

Влад, вы снова ярко показали, что не имеете никакого опыта в db2 и никогда не были DBA. если бы вы имели опыт, вы бы показали бы мне план запроса, а не перечисляли индексы, которые без дополнительной информации все равно особой смысловой нагрузки не несут. если бы вы имели опыт, вы бы знали, что наличие или отсутствие индекса это вообще не о чем, обсуждать имеет смысл только план и статистику по запросу.
например у вас не видно отдельного индекса по WORK_ORDER_NBR, но сказать, что без него будет плохой план не возможно, т.к. есть миллион вариантов, когда выгодней фулскан. кроме этого если речь идет о миграции, сортировка там явно лишняя.
zgur
Уже с Приветом
Posts: 328
Joined: 09 Sep 2002 17:42
Location: NH

Re: Хочу научиться читать SQL...

Post by zgur »

По мне так весь Exists лишний т.к. он присоединяется к основному запросу по первичному ключу. Если exists убрать (мигрировав все условия в главный запрос), то следующей проблемой я бы назвал условие "WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK BETWEEN ? AND ?". такое условие практически никогда не позволяет нспользовать индексы и зависит от внутренней структуры WORK_ORDER_NBR. Я бы постарался его заменить на два независимых условия по WORK_ORDER_NBR и WORK_ORDER_TASK.

Оптимизировать этот конкретный экземпляр не сложно, но присутствие условий типа OR ( 1 = 0 ) , дает повод думать, что SQL динамически сгенерирован и его прямое изменение либо невозможно, либо нетривиально.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zgur wrote:По мне так весь Exists лишний т.к. он присоединяется к основному запросу по первичному ключу. Если exists убрать (мигрировав все условия в главный запрос), то следующей проблемой я бы назвал условие "WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK BETWEEN ? AND ?". такое условие практически никогда не позволяет нспользовать индексы и зависит от внутренней структуры WORK_ORDER_NBR. Я бы постарался его заменить на два независимых условия по WORK_ORDER_NBR и WORK_ORDER_TASK.
тут не соглашусь. exists не должен быть проблемой, т.к. все равно запрос будет переписан оптимизатором и план будет идентичен запросу без exists. WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK может индекс TIIWOTSK использовать.
zgur
Уже с Приветом
Posts: 328
Joined: 09 Sep 2002 17:42
Location: NH

Re: Хочу научиться читать SQL...

Post by zgur »

iDesperado wrote: тут не соглашусь. exists не должен быть проблемой, т.к. все равно запрос будет переписан оптимизатором и план будет идентичен запросу без exists.
В этом конкретном случае join elimination работать не будет т.к. первичный ключ состоит из двух столбцов. Вот похожий пример - если его поменять, чтобы только object_id был в ключе, работает как вы говорите.

Code: Select all

SQL*Plus: Release 12.1.0.2.0 Production on Sun Jan 18 10:14:01 2015

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Sun Jan 18 2015 09:53:00 -08:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> set pages 1000 lines 1000
SQL> CREATE TABLE test   (object_id INTEGER,owner varchar2(32),object_name varchar2(32) );

Table created.

SQL> INSERT INTO test
SELECT object_id,owner,object_name FROM dba_objects WHERE OBJECT_id IS NOT NULL  ;  2  

93646 rows created.

SQL> CREATE UNIQUE INDEX ind ON test (object_id,owner);  

Index created.

SQL> EXEC dbms_stats.gather_table_stats(NULL,'TEST'); 

PL/SQL procedure successfully completed.


SQL> EXPLAIN PLAN  FOR 
SELECT * FROM test t1
WHERE EXISTS (SELECT * FROM test t2 WHERE t1.object_id = t2.OBJECT_id AND t1.owner = t2.owner AND  object_name LIKE 'A%')
AND OBJECT_name LIKE '%A' 
/

Explained.

SQL> SELECT * FROM table(dbms_xplan.display);

PLAN_TABLE_OUTPUT


Plan hash value: 3304307699

-----------------------------------------------------------------------------
| Id  | Operation	     | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |	    |	  1 |	 72 |	288   (1)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT SEMI|	    |	  1 |	 72 |	288   (1)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL  | TEST |  1266 | 45576 |	144   (1)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL  | TEST |  4682 |	164K|	144   (1)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID" AND
	      "T1"."OWNER"="T2"."OWNER")
   2 - filter("OBJECT_NAME" LIKE 'A%')
   3 - filter("OBJECT_NAME" LIKE '%A' AND "OBJECT_NAME" IS NOT NULL)

18 rows selected.

SQL> 
zgur
Уже с Приветом
Posts: 328
Joined: 09 Sep 2002 17:42
Location: NH

Re: Хочу научиться читать SQL...

Post by zgur »

iDesperado wrote: WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK может индекс TIIWOTSK использовать.
При конкатенации, не индекс на индивидуальные колонки, не индекс на обе колонки работать не будетю Тольно function based на эту операцию. Продлжение примера

Code: Select all

SQL> EXPLAIN PLAN  FOR 
SELECT * FROM test t1  WHERE object_id||owner = '122system' ;  2  

Explained.

SQL> SELECT * FROM table(dbms_xplan.display); 

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1357081020

--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |   936 | 33696 |   144   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |   936 | 33696 |   144   (1)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_CHAR("OBJECT_ID")||"OWNER"='122system')


sp123
Уже с Приветом
Posts: 1960
Joined: 24 Feb 2001 10:01
Location: Челябинск -> Everett, WA

Re: Хочу научиться читать SQL...

Post by sp123 »

Запрос действительно простенький. Помимо execution plan не мешало бы также уточнить размеры таблиц и что примерно передается в bind variables в момент запроса - от выгребания, к примеру, 2% или половины большой таблицы рекомендации могут отличаться. А вообще да, динамический SQL - зло. Но видимо, в данном случае была нужда.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

zgur wrote:По мне так весь Exists лишний т.к. он присоединяется к основному запросу по первичному ключу. Если exists убрать (мигрировав все условия в главный запрос), то следующей проблемой я бы назвал условие "WOTSK.WORK_ORDER_NBR || WOTSK.WORK_ORDER_TASK BETWEEN ? AND ?". такое условие практически никогда не позволяет нспользовать индексы и зависит от внутренней структуры WORK_ORDER_NBR. Я бы постарался его заменить на два независимых условия по WORK_ORDER_NBR и WORK_ORDER_TASK.

Оптимизировать этот конкретный экземпляр не сложно, но присутствие условий типа OR ( 1 = 0 ) , дает повод думать, что SQL динамически сгенерирован и его прямое изменение либо невозможно, либо нетривиально.
Это самый лучший и полный анализ. SQL не сгенерирован динамически и первое что было предложено это как раз убрать OR (1=0). Одно лишь это радикально меняет план доступа. Даже убирание одного OR там где колонка FACILITY используется.

EXISTS совершенно не нужен, на результат не влияет но в плане доступа отражается как join.

Что касается конкатенация то во-первых у нас таких конструкции в приложении очень много, не понятно чем они мотивированны и не совсем понятно как влияет на результат. Я уже приводил здесь такую конструкцию для обсуждения но не помню на чем тогда остановились. Во-вторых все таки используется, я чуть позже приведу планы доступа для всех вариантов.


Таблица размером более 10 млн. строк.
Это не из миграции, это OLTP запрос выполняющий сия годами. К нашему огромному удивлению программисты поменяли его на раз-два-три. Обычно они очень не охотно это делают.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zgur,
с конкотенацией у вас совершенно не корректный пример. конечно без хинтов оракл будет фулскан выбирать, т.к. на тех крошечных объемах это безусловно выгодней.
вот пример, где без проблем используется индекс, без FBI:
select /*+ index( c1 test_idx )*/ * from table1 c1 where portfolio_id||status = 'GE07018B000000UPD%';

Code: Select all

----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows   | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |   176K |    11M| 24838   (1)| 00:04:59 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TABLE1   |    176K|    11M| 24838   (1)| 00:04:59 |
|*  2 |   INDEX FULL SCAN           | TEST_IDX |    176K|       | 10173   (1)| 00:02:03 |
----------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("PORTFOLIO_ID"))||SYS_OP_UNDESCEND
              (SYS_OP_DESCEND("GSS_STATUS"))='GE07018B000000UPD%')

понятно, что на небольших объемах сканировать индекс, а потом дергать соответствующие блоки таблицы гораздо затратней, чем считать пару блоков вашей крошечно таблички одним фулсканом.
с join elimination посмотрю чуть позже.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zgur wrote: В этом конкретном случае join elimination работать не будет т.к. первичный ключ состоит из двух столбцов. Вот похожий пример - если его поменять, чтобы только object_id был в ключе, работает как вы говорите.
я не вижу проблем у себя на 11.2:
select * from table1 c1 where no=1 and exists (select 1 from table1 c2 where c2.status = 'MGR' and c1.id = c2.id and c1.portfolio_id=c2.portfolio_id) ;

Code: Select all

---------------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       | 89400 |  5936K|  9375   (1)| 00:01:53 |
|*  1 |  TABLE ACCESS FULL| TABLE1| 89400 |  5936K|  9375   (1)| 00:01:53 |
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("C1"."PORTFOLIO_ID" IS NOT NULL AND "NO"=1 AND 
              "STATUS"='MGR')
как видите в моем случае как полагается запрос переписан.
Update: прошу прощения, забыл про unique в индексе. действительно с уникальным индексом не может переписать. действительно еще одна проблема.
Last edited by iDesperado on 18 Jan 2015 20:22, edited 1 time in total.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

sp123 wrote:Запрос действительно простенький. Помимо execution plan не мешало бы также уточнить размеры таблиц и что примерно передается в bind variables в момент запроса - от выгребания, к примеру, 2% или половины большой таблицы рекомендации могут отличаться. А вообще да, динамический SQL - зло. Но видимо, в данном случае была нужда.
В переменных может быть что угодно, конечно. Это OLTP, и значения берутся из полей окошек.
Больше 10 млн. строк.
А что Вы имеете в виду под "динамический"? То, что переменные не определены?
В нашей терминологии это не динамический а статический запрос в том смысле что план доступа вычисляется и запрос преобразуется в исполняемую форму до выполнения и хранится в БД (не в обычной таблице, а в специальном хранилище). Что касаемо переменных то в ДБ2 есть такое понятие как категория. Есть две основных категорий - одна это когда независимо ни отчего план однозначен, вторая когда план может быть утончен если, например (но не только), известны переменные.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zVlad wrote: первое что было предложено это как раз убрать OR (1=0). Одно лишь это радикально меняет план доступа.
я слышал, что db2/zOS слабоват, но не думал что все на столько фигово
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

Вот планы доступа из DB2 v9.

3333 - исходный запрос
3334 - без OR with FACILITY
3335 - без всех OR
3336 - без EXISTS.


Тут некоторые колонки из двух таблиц: PLAN_TABLE и DSN_STATEMNT. Дана расшифровка METHOD.
Во второй таблице есть цост в милисекундах и в service units. Кроме того указано что этот запрос не однозначен и его неоднозначность от HOST VARIABLES. Программы с такими запросами рекомендуется bind-ить с опцией REOPT(VARS) тогда во время выполнения с известными переменными будет делаться уточнение плана доступа и выбран лучший.

Code: Select all

--  METHOD:                                                                     
--  0 - FIRST TABLE ACCESSED, CONTINUATION OF                                   
--        PREVIOUS TABLE ACCESSED OR NOT USED                                   
--  1 - NESTED LOOP JOIN                                                        
--  2 - MERGE SCAN JOIN                                                         
--  3 - SORTS REQUIRED BY ORDER BY, GROUP BY,                                   
--        SELECT DISTINCT, UNION                                                
--  4 - HYBRID JOIN                                                             
   SELECT                                                                       
     QUERYNO, METHOD, ACCESSTYPE, MATCHCOLS, ACCESSNAME                         
     FROM PLAN_TABLE WHERE QUERYNO IN (3333, 3334, 3335);                       
---------+---------+---------+---------+---------+---------+
    QUERYNO  METHOD  ACCESSTYPE  MATCHCOLS  ACCESSNAME        
---------+---------+---------+---------+---------+---------+
       3333       0  I                   2  TOIWOTS4        
       3333       0  I                   1  TOIWOTSK        
       3334       0  I                   2  TOIWOTSK       
       3334       0  I                   1  TOIWOTSK        
       3335       0  I                   1  TOIWOTS4        
       3335       1  I                   2  TOIWOTSK
       3335       3                      0
       3336       0  I                   1  TOIWOTS4    
DSNE610I NUMBER OF ROWS DISPLAYED IS 7    
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100    
---------+---------+---------+---------+---------+---------+
   SELECT QUERYNO, COST_CATEGORY,      PROCMS,      PROCSU, REASON              
   FROM DSN_STATEMNT_TABLE WHERE QUERYNO IN (3333, 3334, 3335);                 
---------+---------+---------+---------+---------+---------+
    QUERYNO  COST_CATEGORY       PROCMS       PROCSU  REASON  
---------+---------+---------+---------+---------+---------+---------+
       3333  B                      356         3912  HOST VARIABLES  
       3334  B                      274         3004  HOST VARIABLES
       3335  B                        4           43  HOST VARIABLES
       3336  B                        3           33  HOST VARIABLES
DNE610I NUMBER OF ROWS DISPLAYED IS 3    
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100    

zgur
Уже с Приветом
Posts: 328
Joined: 09 Sep 2002 17:42
Location: NH

Re: Хочу научиться читать SQL...

Post by zgur »

iDesperado wrote:zgur,
с конкотенацией у вас совершенно не корректный пример. конечно без хинтов оракл будет фулскан выбирать, т.к. на тех крошечных объемах это безусловно выгодней.
вот пример, где без проблем используется индекс, без FBI:
select /*+ index( c1 test_idx )*/ * from table1 c1 where portfolio_id||status = 'GE07018B000000UPD%';

Code: Select all

----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows   | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |   176K |    11M| 24838   (1)| 00:04:59 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TABLE1   |    176K|    11M| 24838   (1)| 00:04:59 |
|*  2 |   INDEX FULL SCAN           | TEST_IDX |    176K|       | 10173   (1)| 00:02:03 |
----------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("PORTFOLIO_ID"))||SYS_OP_UNDESCEND
              (SYS_OP_DESCEND("GSS_STATUS"))='GE07018B000000UPD%')

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

Посмотрите ваш пример поподробнее. Он не использует индексы в классическом смысле этого понятия - O(log(n)) доступ к записям или "index range scan, index unique scan" в плане. Ваш пример делает index full scan - по сути вертикальная партиция таблицы, без учета стуктуры индкса и возможности быстрого (O(log(n))) поиска по нему. Если рассмотреть вырожденный случай, когда в таблице никаких других полей, кроме тех, что в индексе нет, то index full scan и table full scan будут эквывалентны.

Попробуйте создать пример с index range scan и, скорее всего, вам станет ясно, что это невозможно.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zgur wrote: Посмотрите ваш пример поподробнее. Он не использует индексы в классическом смысле этого понятия - O(log(n)) доступ к записям или "index range scan, index unique scan" в плане. Ваш пример делает index full scan - по сути вертикальная партиция таблицы, без учета стуктуры индкса и возможности быстрого (O(log(n))) поиска по нему. Если рассмотреть вырожденный случай, когда в таблице никаких других полей, кроме тех, что в индексе нет, то index full scan и table full scan будут эквывалентны.
да, пожалуй вы снова правы. index full scan не то, что я хотел показать.

zVlad, так может попросите DBA всетаки показать планы запросов ?
fleshold
Уже с Приветом
Posts: 143
Joined: 29 Apr 2014 12:22

Re: Хочу научиться читать SQL...

Post by fleshold »

По моему вопрос с "подвохом", нет? Оптимизация IN\EXIST выносом в основное тело запроса, исключение\замена на unionы ORов... Это всё азы оптимизации, наверняка известные даже школьникам рисующим сайты на пэхе. (Когда нибудь они тоже сталкиваются с такими проблемами и быстро выгугливают решение.) Не надо даже быть DBA и\или уметь читать планы.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

iDesperado wrote:......

zVlad, так может попросите DBA всетаки показать планы запросов ?
Чем Вас не устраивают те что я (не DBA) уже показал выше?
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zVlad wrote:Чем Вас не устраивают те что я (не DBA) уже показал выше?
тем, что это не планы, а куски сырой информации из plan_table. попросите вашего DBA, он поймет о чем речь. в zOS должны быть какие-то утилиты, которые отформатируют информацию из plan_table, покажет хотя бы косты. на сколько я слышал в LUW db2expln, db2exfmt для этого используют.
хотя собственно смысла уже в планах нет. то что вы не понимаете, как нужно разработчику показать план явственно говорит, что вы нифига не DBA и близко у проектов связанными с db2 не стояли. хотя это было понятно и 5 лет назад, когда вы примитивный SQL не смогли прочесть.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

iDesperado wrote:
zVlad wrote:Чем Вас не устраивают те что я (не DBA) уже показал выше?
тем, что это не планы, а куски сырой информации из plan_table. попросите вашего DBA, он поймет о чем речь. в zOS должны быть какие-то утилиты, которые отформатируют информацию из plan_table, покажет хотя бы косты. на сколько я слышал в LUW db2expln, db2exfmt для этого используют.
То что Вы называете "отформатированная информация" это то что можно взять из PLAN_TABLE (в случае DB2 for zOS и еще ряд других таблиц). Я показал лишь часть PLAN_TABLE с вполне конртерной смысловой информацией. Если Вам этой выдержки не достаточно то скажите что Вам хотелось бы еще увидеть и я Вам это покажу. Но это возможно если только Вы нормальным человеческим техническим языком обясните что Вам не хватает.

Что касаемо cost, то они в том что я показал выше есть. Это столбцы PROCMS, и PROCSU. Первый столбец дает costт в милисекундах (MS), второй в Service Units (SU). Обясните чем Вас не устраивают эти cost-ы?

P.S. "Сырая информация" из PLAN_TABLE. Я смеюсь. Вы хоть немножко думайте прежде чeм говорить. "Отформатированная информация" - второй прикол. Если Вы не умеете читать информацию из PLAN_TABLE зaчем Вы вообще ввязываетесь в дискуссии на темы SQL tuning?
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zVlad wrote: То что Вы называете "отформатированная информация" это то что можно взять из PLAN_TABLE (в случае DB2 for zOS и еще ряд других таблиц). Я показал лишь часть PLAN_TABLE с вполне конртерной смысловой информацией. Если Вам этой выдержки не достаточно то скажите что Вам хотелось бы еще увидеть и я Вам это покажу. Но это возможно если только Вы нормальным человеческим техническим языком обясните что Вам не хватает.
Влад, ну сходите к DBA, какого черта я должен вам разжевывать основы ? спросите у девелоперов наконец. план это граф, у вас же просто неотсортированные сырые данные, с небольшой частью сырых данных плана. я не могу прочесть документацию для db2, потому что у IBM она самая идиотская из всех субд какие я встречал, а встречал я не мало. судя по всему нужно запускать команду EXPLAIN которая из сырых данных PLAN_TABLE создаст EXPLAIN tables, которые какие-то тулзы должны показывать
http://www-01.ibm.com/support/knowledge ... ables.dita

DB2® uses EXPLAIN tables to store information about the access plan that is uses to process SQL queries, and the tables are populated when the EXPLAIN function is invoked by you, by bind options, or by certain optimization tools. You can create one or more EXPLAIN tables that are qualified by a user ID for your own use and EXPLAIN tables that are qualified by SYSIBM.
http://www-01.ibm.com/support/knowledge ... ta?lang=en

в LUW план выглядит примерно так

Code: Select all


Access Plan:
-----------
        Total Cost:             71.3646
        Query Degree:           1

                         Rows
                        RETURN
                        (   1)
                         Cost
                          I/O
                          |
                      6.64478e-05
                        NLJOIN
                        (   2)
                        71.3646
                        42.3992
               /----------+----------\
           1.13333                 5.86304e-05
           FETCH                     FETCH
           (   3)                    (   5)
           15.1468                   47.1541
              2                      33.8817
         /---+----\                /---+----\
     1.13333       17056       21.1132      360107
     IXSCAN   TABLE: WSCOMUSR  RIDSCN   TABLE: WSCOMUSR
     (   4)      SCHCONFIG     (   6)      SCHSTATUS
     7.58191        Q1         15.1594        Q2
        1                         2
       |                         |
      17056                    21.1132
 INDEX: WSCOMUSR               SORT
    I0000321                   (   7)
       Q1                      15.159
                                  2
                                 |
                               21.1132
                               IXSCAN
                               (   8)
                               15.1559
                                  2
                                 |
                               360107
                           INDEX: WSCOMUSR
                              I0000762
                                 Q2

zVlad wrote: Что касаемо cost, то они в том что я показал выше есть. Это столбцы PROCMS, и PROCSU. Первый столбец дает costт в милисекундах (MS), второй в Service Units (SU). Обясните чем Вас не устраивают эти cost-ы?
тем что это время одного компонента, а не кост. кост это попугай, в котором учитывается процессорное время, затраты и/о, затраты памяти и миллион других вещей. Влад, это основы.
zVlad wrote:
P.S. "Сырая информация" из PLAN_TABLE. Я смеюсь. Вы хоть немножко думайте прежде чeм говорить. "Отформатированная информация" - второй прикол. Если Вы не умеете читать информацию из PLAN_TABLE зaчем Вы вообще ввязываетесь в дискуссии на темы SQL tuning?
Влад, с вашими знаниями, с вашими сочинениями о проектах и должности DBA не надо лезть на ражен. изучайте команду EXPLAIN и спросите у DBA как в db2 получить графически план. я очень невысокого мнения о db2, но все таки не верю, что в 21 веке кто-то планы в командной строке готовит и читает. должны быть какие-то графические тулзы для DBA, мир Unix этот этап прошел в 90х.
Last edited by iDesperado on 19 Jan 2015 18:57, edited 1 time in total.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

iDesperado, если Вы может понимать только картинки (которую я безусловно имею), то это очень многое говорит не обо мне или o DB2, а как раз наоборот - о Вас. Хотя мне с Вами уже давно все понятно и я это уже извучивал, не хочу повторятся.

Картинки, которые Вы так любите, строятся исключительно на основе "сырой" информации из PLAN_TABLE. Исключительно означает что ничего такого особого чего нет в PLAN_TABLE в картинках нет и быть не может. Если бы Вы меня спросили об информации которую я не показал в моем запросе в PLAN-TABLE, то я бы Вам с радостью эту информацию предоставил. Но Вы не знаете что спросить и поэтому переходите на личность.

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

Пошлый Вы человек, iDesperado, и общаться с Вами гадко и противно.

P.S. Еще, блин, про EXPLAIN что-то говорите. А подумать каким это я чудесным образом получил информацию в PLAN_TABLE Вам чего не хватило? Ума, или храбрости, а может такого качества как порядочность? Обясните.
iDesperado
Уже с Приветом
Posts: 1332
Joined: 28 Nov 2008 17:50

Re: Хочу научиться читать SQL...

Post by iDesperado »

zVlad wrote:iDesperado, если Вы может понимать только картинки (которую я безусловно имею), то это очень многое говорит не обо мне или o DB2, а как раз наоборот - о Вас. Хотя мне с Вами уже давно все понятно и я это уже извучивал, не хочу повторятся.
если вы действительно имеете картинку, вас ни на какие мысли не навела она ? не удивило, что на картинке упорядочный граф, а не плеин таблица с записями в рандомном порядке ? что около каждой операции ее кост, информация об индексе, предикатах, количестве сортировок, процент чтений с хдд и множество других вещей ?
zVlad wrote: Пошлый Вы человек, iDesperado, и общаться с Вами гадко и противно.
гадко в вашем возрасте изображать из себя DBA, судорожно выясняя, что такое план.
zVlad
Уже с Приветом
Posts: 15071
Joined: 30 Apr 2003 16:43

Re: Хочу научиться читать SQL...

Post by zVlad »

iDesperado wrote:.....
если вы действительно имеете картинку, вас ни на какие мысли не навела она ? не удивило, что на картинке упорядочный граф, а не плеин таблица с записями в рандомном порядке ? что около каждой операции ее кост, информация об индексе, предикатах, количестве сортировок, процент чтений с хдд и множество других вещей ?
....
Я Вас когда-нибудь обманывал? Конечно имею я картинку. Почитайте на интернете про Data Studio for DB2 - вот это тот тул которым мы смотрим картинки.

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

Вот и с картинками Вы так уперлись потому больше Вам упираться не во что, а хочется. Так что слушайте.
Представьте себе приложение с более чем тремя тысячами программ и с несколькими сотнями SQL statements в каждой и вот Вы рассматривая картинку одного SQL понимаете что нужно переделать имеющийся индекс или создать новый или Вы нашли, как Вам кажется неудачный индекс и считаете что его лучше удалить. Как Вы будете решать такую задачку? Будете смотреть на каждую из сотен тысяч возможных картинок? Сколько Вам на это время понадобится?
Что я хочу сказать. Картинка, граф конечно это хорошо чтобы понять общую картину плана доступа конкретного запроса, но чтобы сделать что-либо серьезное для всей совокупности запросов приложения картинки Вам не помогут и Вы их для этого использовать не будете.
Вот из приведенного мной примера можно увидеть индекс TIIWOTS4. У него много колонок и есть сильные сомнения что есть хотя бы один запрос среди многих сотен тысяч который бы использовал все эти колонки. А сколько максимум колонок этого индекса используется хотя бы в одном запросе? Как Вы решите такую задачу с помощью картинок? Как Вы вообще будете решать такую задачу. Подумайте, но не спешите с ответом. Я пока в ресторан съезжу - праздник сегодня. Вы кстати купель принимали сегодня?
User avatar
wassup
Уже с Приветом
Posts: 736
Joined: 30 Mar 2006 09:08
Location: Arch Linux world

Re: Хочу научиться читать SQL...

Post by wassup »

iDesperado wrote:я очень невысокого мнения о db2, но все таки не верю, что в 21 веке кто-то планы в командной строке готовит и читает. должны быть какие-то графические тулзы для DBA, мир Unix этот этап прошел в 90х.
wat?

Человеку который боится работать с коммандной строкой делать в администрировании нечего. В особенности в администрировании систем хранения данных.
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: Хочу научиться читать SQL...

Post by tengiz »

wassup wrote:Человеку который боится работать с коммандной строкой делать в администрировании нечего. В особенности в администрировании систем хранения данных.
По-мому Вы смешиваете "набирать команды в кс" с чтением разнообразной информации в различных видах. Одно дело не боятся фигачить пальцАми на клаве, но любоваться ASCII артом в ситуации, когда картинка будет нагляднее портянки на пару тыщ строк - это совсем другое. Хотя своя прелесть в этом есть.

Code: Select all

                             ,-.
       ___,---.__          /'|`\          __,---,___
    ,-'    \`    `-.____,-'  |  `-.____,-'    //    `-.
  ,'        |           ~'\     /`~           |        `.
 /      ___//              `. ,'          ,  , \___      \
|    ,-'   `-.__   _         |        ,    __,-'   `-.    |
|   /          /\_  `   .    |    ,      _/\          \   |
\  |           \ \`-.___ \   |   / ___,-'/ /           |  /
 \  \           | `._   `\\  |  //'   _,' |           /  /
  `-.\         /'  _ `---'' , . ``---' _  `\         /,-'
     ``       /     \    ,='/ \`=.    /     \       ''
             |__   /|\_,--.,-.--,--._/|\   __|
             /  `./  \\`\ |  |  | /,//' \,'  \
            /   /     ||--+--|--+-/-|     \   \
           |   |     /'\_\_\ | /_/_/`\     |   |
            \   \__, \_     `~'     _/ .__/   /
             `-._,-'   `-._______,-'   `-._,-'

 

Cheers

Return to “Вопросы и новости IT”