Ваши проблемы от использования неверных типов данных, в частности для хранения даты использование числа вместо даты. Я буду рассматривать упрощенный запрос с отбором по дате
select * from shax where zam_date>20060301 Выжимки из вашего 10053:
Плохой, данные по таблице:
Table stats Table: SHAX Alias: SHAX
TOTAL :: CDN: 10411456 NBLKS: 59708 AVG_ROW_LEN: 39
SINGLE TABLE ACCESS PATH
Column: ZAM_DATE Col#: 2 Table: SHAX Alias: SHAX
NDV: 2264 NULLS: 0 DENS: 4.4170e-004 LO: 18991230 HI: 20090803
NO HISTOGRAM: #BKT: 1 #VAL: 2
TABLE: SHAX ORIG CDN: 10411456 ROUNDED CDN: 288812 CMPTD CDN: 288812
Хороший, данные по таблице:
Table stats Table: SHAX Alias: SHAX
TOTAL :: CDN: 8207527 NBLKS: 46960 AVG_ROW_LEN: 39
SINGLE TABLE ACCESS PATH
Column: ZAM_DATE Col#: 2 Table: SHAX Alias: SHAX
NDV: 2152 NULLS: 0 DENS: 4.6468e-004 LO: 18991230 HI: 20060817
NO HISTOGRAM: #BKT: 1 #VAL: 2
Плохой, рассмотрение индекса по ZAM_DATE :
Access path: index (scan)
Index: ZAM_DATE
TABLE: SHAX
RSC_CPU: 0 RSC_IO: 10333
IX_SEL: 2.7740e-002 TB_SEL: 2.7740e-002
BEST_CST: 5744.00 PATH: 2 Degree: 1
Хороший, рассмотрение индекса по ZAM_DATE:
Access path: index (scan)
Index: ZAM_DATE
TABLE: SHAX
RSC_CPU: 0 RSC_IO: 125
IX_SEL: 4.8243e-004 TB_SEL: 4.8243e-004
BEST_CST: 125.00 PATH: 4 Degree: Селективность для условия c1 > value вычисляется по формуле (Hi - value) / (Hi - Lo) т.е. у Вас: Плохой= (20090803-20060301)/(20090803-18991230) = 0,0277398590180006 (IX_SEL: 2.7740e-002 TB_SEL: 2.7740e-002) Хороший=(20060817-20060301)/(20090803-18991230) = 0,000469273072365364 (IX_SEL: 4.8243e-004 TB_SEL: 4.8243e-004, немножко не совпало, но не будем сейчас разбираться , порядок тот же)
Соответственно число строк ожидаемое после применения предиката zam_date>20060301 Плохой: 10411456 * 0,0277398590180006 = 288812 , и индекс кажется не выгодным Хороший: 8207527 * 0,000469273072365364= 3851, тут доступ по индексу становится выгодным с точки зрения оптимизатора.
Т.е. проблема в том, что в интервал между числами 20090803 - 20060301 влезает слишком много возможных значений, 30502 дней, больше 83 лет. В то время когда между датами 03.08.2009 и 01.03.2006 всего 3 года.
Т.е. ваша основная проблема в неверном выборе типов полей для хранения, кроме того наличие в "плохом" случае данных в будущее ( hi =20090803 против hi=20060817).
Возможно в вашем случае может помочь гистограмма по столбцу ZAM_DATE, если нет то хинтование запроса или построение OUTLINE.
Andrei Kiselev -- The views expressed are my own and not necessarily those of my hedgehog |