powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему перестал использоваться индекс?
23 сообщений из 23, страница 1 из 1
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #39399278
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Делал пересчет статистики, в TOAD по индексу не вижу каких-либо проблем
Статистики чего?
Если таблицы, то чтобы не гадать, снимай 10053
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399330
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как насчет гистограмм -- может данные за этот месяц занимают полтаблицы
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399350
dimyaz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alibek B.,

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

Может кто-то запустил такой же запрос, но за больший периоД и первый раз оптимизатор решил привязать его план к фулскану.
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399354
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У него все-таки литералы, а не бинды
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #39399371
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
10053 читается в сыром виде
tkprof только для 10046
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399377
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|Alibek B.Делал пересчет статистики, в TOAD по индексу не вижу каких-либо проблем
Статистики чего?
Если таблицы, то чтобы не гадать, снимай 10053
Тут нужно было писать дополнение?
автора если собирал не табличную статистику, то собери ее
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399387
fortnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно попробовать пересобрать статистику таблицы + индекса , предварительно полностью удалив предыдущую.
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #39399407
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Trace file: billing_lgwr_23999.trc



Не тот файл смотришь . Это трейс lgwr (background process). Твой будет называться sid_ora_pid_traceid.trc. Check TRACEFILE_IDENTIFIER .
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #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
Почему перестал использоваться индекс?
    #39399606
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прикладываю в аттаче.
Странно, что CBO посчитал оптимальным делать полный скан таблицы (записи в таблице более-менее ровно распределены по месяцам, с постепенным увеличением количества записей в месяц), но видимо у него были свои соображения.
Мне нужно получить данные примерно за 6 лет и мне быстрее оказалось прогнать этот запрос в цикле с суточным интервалом (при таком интервале индекс используется), чем запускать несколько раз для годовых периодов.
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #39399644
veep_in_office
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alibek B.,

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

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

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

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

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

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

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

Это радует, что совет всё таки был замечен :)
...
Рейтинг: 0 / 0
Почему перестал использоваться индекс?
    #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
23 сообщений из 23, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему перестал использоваться индекс?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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