Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему перестал использоваться индекс? / 23 сообщений из 23, страница 1 из 1
06.02.2017, 13:57
    #39399255
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Есть таблица с таким DDL:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE TABLE BM_PERIODIC_ACCT
(
  PERIODIC_ACCT_ID      NUMBER                  NOT NULL,
  SERVICE_TARIFF_ID     NUMBER                  NOT NULL,
  TARIFFEL_ID           NUMBER                  NOT NULL,
  PERIOD_START          DATE                    NOT NULL,
  PERIOD_STOP           DATE                    NOT NULL,
  MOMENT                DATE                    NOT NULL,
  PERIOD_CF             NUMBER(15,5)            NOT NULL,
  POSTPAID_CALC_MOMENT  DATE
);

CREATE INDEX PER_ACCT_MOMENT_IDX ON BM_PERIODIC_ACCT (MOMENT)
NOPARALLEL
COMPRESS 1;



Ранее проблем не замечал, но сегодня вдруг обнаружил, что запрос с этой таблицей выполняется долго.
Сделал план для такого запроса:
Код: plsql
1.
2.
3.
select *
from BM_PERIODIC_ACCT PA
where PA.MOMENT between DATE'2016-01-01' and DATE'2016-02-01'


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
--------------------------------------------------------------------------------------
| Id  | Operation         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                  | 71838 |  3016K|  2665   (2)| 00:00:32 |
|*  1 |  TABLE ACCESS FULL| BM_PERIODIC_ACCT | 71838 |  3016K|  2665   (2)| 00:00:32 |
--------------------------------------------------------------------------------------

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

   1 - filter("PA"."MOMENT"<=TO_DATE(' 2016-02-01 00:00:00', 'syyyy-mm-dd 
              hh24:mi:ss') AND "PA"."MOMENT">=TO_DATE(' 2016-01-01 00:00:00', 'syyyy-mm-dd 
              hh24:mi:ss'))
Делал пересчет статистики, в TOAD по индексу не вижу каких-либо проблем:
ParameterValueIndex NamePER_ACCT_MOMENT_IDXIndex TypeNORMALUniquenessNONUNIQUEStatusVALIDTableBM_PERIODIC_ACCTTable TypeTABLETablespaceBM_INDEXBuffer PoolDEFAULTPartitionedNoTemporaryNoInitial Transactions2Max Transactions255Initial Extent Size64 KbMinimum Extents1Maximum Extents2 147 483 645Percent Free10Degree1Instances1Last Analyzed06.02.2017 13:45:12BLevel2Leaf Blocks7 353Distinct Keys307 203Avg Leaf Blocks Per Key1Avg Data Blocks Per Key1Clustering Factor311 228Num Rows1 471 631Sample Size1 471 631GeneratedNJoin IndexNo

Что может быть причиной того, что индекс не используется?
________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
06.02.2017, 14:22
    #39399275
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Если указать хинт:
Код: plsql
1.
2.
3.
select /*+ INDEX(PA PER_ACCT_MOMENT_IDX) */ *
from BM_PERIODIC_ACCT PA
where PA.MOMENT between DATE'2016-01-01' and DATE'2016-02-01'


то индекс используется и запрос выполняется быстро.
А почему CBO может считать, что индекс использовать не следует?
...
Рейтинг: 0 / 0
06.02.2017, 14:24
    #39399278
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.Делал пересчет статистики, в TOAD по индексу не вижу каких-либо проблем
Статистики чего?
Если таблицы, то чтобы не гадать, снимай 10053
...
Рейтинг: 0 / 0
06.02.2017, 15:13
    #39399330
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Как насчет гистограмм -- может данные за этот месяц занимают полтаблицы
...
Рейтинг: 0 / 0
06.02.2017, 15:36
    #39399350
dimyaz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

Причин может быть очень много.
Надо 10053 снимать, чтобы понять.

Может кто-то запустил такой же запрос, но за больший периоД и первый раз оптимизатор решил привязать его план к фулскану.
...
Рейтинг: 0 / 0
06.02.2017, 15:40
    #39399354
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
У него все-таки литералы, а не бинды
...
Рейтинг: 0 / 0
06.02.2017, 15:43
    #39399358
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
В TOAD я выбрал индекс и выполнил команду Analyze Index, в статусной строке я получил сообщение, что статистика пересчитана. По всей видимости статистика индекса.

Как снять 10053?
Выполнил команду ALTER SESSION SET EVENTS='10053 trace name context forever, level 1', затем запрос, затем ALTER SESSION SET EVENTS '10053 trace name context off'.
В каталоге bdump появился файл billing_lgwr_23999.trc.
Я выполнил команду tkprof billing_lgwr_23999.trc billing_lgwr_23999.res, файл billing_lgwr_23999.res создался, но я не нахожу в нем полезной информации:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
$cat billing_lgwr_23999.res 

TKPROF: Release 10.2.0.4.0 - Production on Mon Feb 6 15:39:12 2017

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

Trace file: billing_lgwr_23999.trc
Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing 
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************
Trace file: billing_lgwr_23999.trc
Trace file compatibility: 10.01.00
Sort options: default

       1  session in tracefile.
       0  user  SQL statements in trace file.
       0  internal SQL statements in trace file.
       0  SQL statements in trace file.
       0  unique SQL statements in trace file.
   26570  lines in trace file.
       0  elapsed seconds in trace file.
...
Рейтинг: 0 / 0
06.02.2017, 15:52
    #39399371
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
10053 читается в сыром виде
tkprof только для 10046
...
Рейтинг: 0 / 0
06.02.2017, 15:55
    #39399377
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
AlexFF__|Alibek B.Делал пересчет статистики, в TOAD по индексу не вижу каких-либо проблем
Статистики чего?
Если таблицы, то чтобы не гадать, снимай 10053
Тут нужно было писать дополнение?
автора если собирал не табличную статистику, то собери ее
...
Рейтинг: 0 / 0
06.02.2017, 16:05
    #39399387
fortnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Можно попробовать пересобрать статистику таблицы + индекса , предварительно полностью удалив предыдущую.
...
Рейтинг: 0 / 0
06.02.2017, 16:11
    #39399395
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Вячеслав Любомудров10053 читается в сыром виде
В таком случае там нет полезных данных.
В файле содержится много записей вида:
Код: plaintext
1.
2.
*** 2017-02-06 15:37:31.604
Warning: log write time 2180ms, size 1KB

Если период сократить до суток, то индекс используется:
Код: plsql
1.
2.


select *
from BM_PERIODIC_ACCT PA
where PA.MOMENT between DATE'2016-01-01' and DATE'2016-01-02'
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
---------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                     |   607 | 27315 |   135   (0)| 00:00:02 |
|   1 |  TABLE ACCESS BY INDEX ROWID| BM_PERIODIC_ACCT    |   607 | 27315 |   135   (0)| 00:00:02 |
|*  2 |   INDEX RANGE SCAN          | PER_ACCT_MOMENT_IDX |   607 |       |     6   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("PA"."MOMENT">=TO_DATE(' 2016-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
              "PA"."MOMENT"<=TO_DATE(' 2016-01-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

Стало быть с индексом все в порядке, это у меня такие данные?
...
Рейтинг: 0 / 0
06.02.2017, 16:20
    #39399407
ora601
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.Trace file: billing_lgwr_23999.trc



Не тот файл смотришь . Это трейс lgwr (background process). Твой будет называться sid_ora_pid_traceid.trc. Check TRACEFILE_IDENTIFIER .
...
Рейтинг: 0 / 0
06.02.2017, 17:07
    #39399451
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Точно, спасибо.
А на что именно смотреть? Там около 30КБ.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SYSTEM STATISTICS INFORMATION
*****************************
  Using NOWORKLOAD Stats
  CPUSPEED: 1251 millions instruction/sec
  IOTFRSPEED: 4096 bytes per millisecond (default is 4096)
  IOSEEKTIM: 10 milliseconds (default is 10)
***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: BM_PERIODIC_ACCT  Alias: BM_PERIODIC_ACCT
    #Rows: 1459524  #Blks:  12009  AvgRowLen:  43.00
Index Stats::
  Index: PERIODIC_ACCT_PK  Col#: 1
    LVLS: 2  #LB: 4091  #DK: 1456301  LB/K: 1.00  DB/K: 1.00  CLUF: 1456265.00
  Index: PER_ACCT_MOMENT_IDX  Col#: 6
    LVLS: 2  #LB: 7353  #DK: 307203  LB/K: 1.00  DB/K: 1.00  CLUF: 311228.00
  Index: PER_ACCT_SERVICE_IDX  Col#: 2
    LVLS: 2  #LB: 3003  #DK: 31357  LB/K: 1.00  DB/K: 40.00  CLUF: 1262968.00
  Index: PER_ACCT_START_IDX  Col#: 4
    LVLS: 2  #LB: 6817  #DK: 675  LB/K: 10.00  DB/K: 57.00  CLUF: 38589.00
  Index: PER_ACCT_STOP_IDX  Col#: 5
    LVLS: 2  #LB: 6625  #DK: 585  LB/K: 11.00  DB/K: 73.00  CLUF: 43211.00
  Index: PER_ACCT_TARIFFEL_IDX  Col#: 3
    LVLS: 2  #LB: 5915  #DK: 121  LB/K: 48.00  DB/K: 950.00  CLUF: 115064.00
***************************************
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
SINGLE TABLE ACCESS PATH
  -----------------------------------------
  BEGIN Single Table Cardinality Estimation
  -----------------------------------------
  Column (#6): MOMENT(DATE)
    AvgLen: 8.00 NDV: 297876 Nulls: 0 Density: 3.3571e-06 Min: 2455349 Max: 2457788
    Histogram: HtBal  #Bkts: 254  UncompBkts: 254  EndPtVals: 255
  Table: BM_PERIODIC_ACCT  Alias: BM_PERIODIC_ACCT
    Card: Original: 1459524  Rounded: 71838  Computed: 71837.78  Non Adjusted: 71837.78
  -----------------------------------------
  END   Single Table Cardinality Estimation
  -----------------------------------------
  Access Path: TableScan
    Cost:  2665.46  Resp: 2665.46  Degree: 0
      Cost_io: 2629.00  Cost_cpu: 547368929
      Resp_io: 2629.00  Resp_cpu: 547368929
  Access Path: index (RangeScan)
    Index: PER_ACCT_MOMENT_IDX
    resc_io: 15683.00  resc_cpu: 147178204
    ix_sel: 0.04922  ix_sel_with_filters: 0.04922
    Cost: 15692.80  Resp: 15692.80  Degree: 1
  Best:: AccessPath: TableScan
         Cost: 2665.46  Degree: 1  Resp: 2665.46  Card: 71837.78  Bytes: 0
***************************************
OPTIMIZER STATISTICS AND COMPUTATIONS
***************************************
GENERAL PLANS
***************************************
Considering cardinality-based initial join order.
Permutations for Starting Table :0
***********************
Join order[1]:  BM_PERIODIC_ACCT[BM_PERIODIC_ACCT]#0
***********************
Best so far: Table#: 0  cost: 2665.4612  card: 71837.7835  bytes: 3089034
(newjo-stop-1) k:0, spcnt:0, perm:1, maxperm:80000
*********************************
Number of join permutations tried: 1
*********************************
Final - All Rows Plan:  Best join order: 1
  Cost: 2665.4612  Degree: 1  Card: 71838.0000  Bytes: 3089034
  Resc: 2665.4612  Resc_io: 2629.0000  Resc_cpu: 547368929
  Resp: 2665.4612  Resp_io: 2629.0000  Resc_cpu: 547368929
kkoipt: Query block SEL$1 (#0)
Или лучше приложить в спойлере весь файл?
...
Рейтинг: 0 / 0
06.02.2017, 18:06
    #39399505
ora601
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

Лучше весь .

Код: plsql
1.
2.
3.
4.
 Access Path: TableScan
    Cost:  2665.46  
  Access Path: index (RangeScan)
    Cost: 15692.80  



Собственно причина почему выбран фтс. А теперь вспоминаем весь список oracle optimizer settings/features которые влияют на index cost в том числе - optimizer_index_cost_adj, sreadtim (system statistics) и проверяем их.
...
Рейтинг: 0 / 0
06.02.2017, 19:59
    #39399606
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Прикладываю в аттаче.
Странно, что CBO посчитал оптимальным делать полный скан таблицы (записи в таблице более-менее ровно распределены по месяцам, с постепенным увеличением количества записей в месяц), но видимо у него были свои соображения.
Мне нужно получить данные примерно за 6 лет и мне быстрее оказалось прогнать этот запрос в цикле с суточным интервалом (при таком интервале индекс используется), чем запускать несколько раз для годовых периодов.
...
Рейтинг: 0 / 0
06.02.2017, 20:32
    #39399644
veep_in_office
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

Таблица размером в 30 мегабайт (70 000>записей). Я бы тоже на месте оптимизатора не стал бы фулскан делать.

Говорите в цикле посуточно быстрее? А попробуйте в цикле по rowid или pk с обработкой и агрегацией. Уверяю будет еще быстрее и докажет эффективность фулскана.
...
Рейтинг: 0 / 0
07.02.2017, 02:05
    #39399741
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

в общем-то, оракл все правильно сделал(если не учитывать насколько у тебя таблица и индекс закэшированы):
при IRS у тебя 367 блоков должно считаться из индекса(из 7тысяч с лишним блоков в индексе) и сделать 71800 лукапов в таблицу по table access by rowid, при том что вся таблица у тебя всего лишь 12тысяч блоков
а при fts всего лишь считать 12 тысяч блоков по 16 блоков за раз. На современных нормально работающих( не перегруженных по IO) системах скорость многоблочного чтения почти не отличается от одноблочного.

Alibek B.то индекс используется и запрос выполняется быстро.а ты проверял-то полное выполнение запроса или тупо до первых отфетченных записей? По-хорошему даже если разница и будет в пользу IRS, то должна быть небольшая
...
Рейтинг: 0 / 0
07.02.2017, 15:36
    #39400218
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
xtenderа ты проверял-то полное выполнение запроса или тупо до первых отфетченных записей?
В том запросе, который был приведен в самом начале (простой select из одной таблицы) я всю выборку не получал, только первые записи. В конечном варианте в запросе будет группировка по датам и запрос вернет не более 31 строки.
...
Рейтинг: 0 / 0
07.02.2017, 17:08
    #39400288
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

Преждевременная оптимизация...
...
Рейтинг: 0 / 0
07.02.2017, 17:12
    #39400296
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Все началось с того, что запросы, которые я использовал ранее, вдруг стали выполнятся значительно дольше.
В процессе выяснения причин оказалось, что по таблице BM_PERIODIC_ACCT почему-то перестал использоваться индекс.
Если делать запрос по большому периоду, он выполняется очень долгое время или вообще зависает. А посуточный проход в цикле получился быстрее и более предсказуемо.

Также я выполнил совет по сбросу статистики не только для индексов, но и для таблицы - и похоже помогло, запрос за месячный период снова использует индекс.
...
Рейтинг: 0 / 0
09.02.2017, 09:44
    #39401398
Nobody1111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Вячеслав ЛюбомудровУ него все-таки литералы, а не бинды

зависит от параметра cursor_sharing
...
Рейтинг: 0 / 0
09.02.2017, 11:03
    #39401458
fortnet
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Alibek B.,

Это радует, что совет всё таки был замечен :)
...
Рейтинг: 0 / 0
24.03.2017, 11:44
    #39426403
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему перестал использоваться индекс?
Есть такой запрос:
Код: plsql
1.
2.
3.
4.
select /*+ index(SM SVRM_SERVICE_IDX) */ S.SERVICE_ID
from TMP_INSTALL_BASE T
join SERVICES S on (S.TARIFF_ID = T.TARIFF_ID and S.STATUS != -20)
join BM_SERVICE_MONEY SM on (SM.SERVICE_ID = S.SERVICE_ID)


Выполняется практически мгновенно, возвращает меньше десятка записей.
Если убираю хинт, выполняется долго (3-4 минуты).
Планы с хинтом и без хинта отличаются (с хинтом INDEX RANGE SCAN и NL, без хинта INDEX FAST FULL SCAN и HASH JOIN).
В таблице BM_SERVICE_MONEY сотни миллионов записей. Каких-либо нестандартных вещей или больших изменений данных с ней не делалось.
Индекс SVRM_SERVICE_IDX составной (состоит из полей SERVICE_ID, FDATE).
Мне не совсем понятно, почему оптимизатор ошибается.
Трассировку 10053 я пока не делал, может быть тут есть какая-то очевидная причина?
Может быть нужно как-то задействовать поле FDATE, чтобы индекс был задействован?

При этом есть еще такой запрос, использующий результаты предыдущего запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with L as
(
  select S.SERVICE_ID, sum(SM.SERVICE_AMOUNT) as QTY, sum(SM.MONEY) as SUM, trunc(max(SM.MOMENT)) as LAST, max(SM.TDATE) as END
  from TMP_INSTALL_BASE T
  join SERVICES S on (S.TARIFF_ID = T.TARIFF_ID and S.STATUS != -20)
  join BM_SERVICE_MONEY SM on (SM.SERVICE_ID = S.SERVICE_ID)
  where SM.PERIODIC_ACCT_ID is not null
  group by S.SERVICE_ID
  --having sum(SM.SERVICE_AMOUNT) >= 12
)
select S.SERVICE_ID--, S.LOGIN, S.RECKONING_DATE, S.START_DATE, S.STOP_DATE, L.QTY, L.SUM, L.LAST, L.END
from L
join SERVICES S on (S.SERVICE_ID = L.SERVICE_ID)
join CUSTOMERS C on (C.CUSTOMER_ID = S.CUSTOMER_ID)
join BM_CUSTOMER_CONTACT CC on (CC.CUSTOMER_ID = C.CUSTOMER_ID and CC.CONTACT_DICT_ID = 100)
join SERVICES S0 on (S0.ACCOUNT_ID = S.ACCOUNT_ID and S0.STATUS > 0 and S0.TARIFF_ID = 1 and S0.LOGIN = CC.VALUE)
join TMP_INSTALL_TARIFF ST on (ST.PARENT_ID = S.TARIFF_ID)
left join SERVICES SS on (SS.ACCOUNT_ID = S.ACCOUNT_ID and SS.STATUS != -20 and SS.TARIFF_ID = ST.TARIFF_ID)


Целиком он выполняется быстро (400мс после очистки кеша).
Но если убрать последнюю строку с LEFT JOIN, то выполнение занимает 3-4 минуты.
В этом тексте запроса FDATE вообще отсутствует.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему перестал использоваться индекс? / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]