powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Informix [игнор отключен] [закрыт для гостей] / Сыпанулся индекс на фрагментированной таблице
51 сообщений из 51, показаны все 3 страниц
Сыпанулся индекс на фрагментированной таблице
    #38991395
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сыпанулся индекс на фрагментированной таблице (oncheck –cI <имя индекса>.)
Таблица большая 550 Гб, почти 600 млн. строк. Обращения к этой таблице (insert, update, delete) происходят в режиме 24 Х 7. Заблокировать доступ к таблице не представляется возможным.
Разворачивание БД из бэкапа займет около 8 часов. Проверка всех данных таблицы и индексов еще часов 12.
Посоветуйте пожалуйста как исправить эту ситуацию с наименьшими потерями по времени?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991403
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл написать. Версия 11.70.FC6
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991443
DrGonzo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991500
яфшуеі
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
online то конечно хорошо, хоть он online токо по тому, что не нужна блокировка таблицы, блокировки строк все-равно будут
нужно также учитывать специфику приложений
не забывайте про PDQ при построении индекса
последний раз когда делал online вылилось нехорошими последствиями и пришлось тупо перезапускать
сервер из-за малюсенького индекса.
Если у вас есть репликация - не факт что на DR сервере битый индекс, возможно стоит перейти туда.
Проверить битый ли там индекс достаточно запросом, который будет использовать данный индекс на проблемных значениях.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991546
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за советы.
База без реплики.
Индекс по полю c типом DATE. Индекс чуть более 10 Гб
Пока пришел к решению, что надо сделать на бэкапе (проверить сколько по времени, один ли индекс поврежден и т.д)
drop index
create index ... online.


1. Можно по-подробнее, что может быть плохого?
2. PDQ выставить в 0 ? Учитывая что в этой таблице в течении всего дня (без перерывов делаются вставки и удаления строк)
Т.е. отдать приоритет всем DML операциям, а затем созданию индекса.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991693
яфшуеі
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PDQ нужно использовать(включить) при создании индекса.
т.е. помимо конф. параметра MAX_PDQPRIORITY
нужно выставить переменную PDQPRIORITY или через оператор set ...
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38991705
яфшуеі
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Б1. Можно по-подробнее, что может быть плохого?



1. Некое замедление в работе, местами м.б. значительное
2. Если приложение при старте парсит а потом по мере надобности візівает запросі - после удаления
индекса возможно будет нужен перезапуск приложения.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38992082
Сергей БСпасибо за советы.
База без реплики.
Индекс по полю c типом DATE. Индекс чуть более 10 Гб
Пока пришел к решению, что надо сделать на бэкапе (проверить сколько по времени, один ли индекс поврежден и т.д)
drop index
create index ... online.


1. Можно по-подробнее, что может быть плохого?
2. PDQ выставить в 0 ? Учитывая что в этой таблице в течении всего дня (без перерывов делаются вставки и удаления строк)
Т.е. отдать приоритет всем DML операциям, а затем созданию индекса.

Блииин !!! Ну зачем же дроп-то сначала ?!!!!

Останетесь без индекса (хоть и битого) - прощай производительность (возможно в разы - сиквенс скан на 600 миллионов строк на каждый раз когда был нужен индекс вы себе представили да ?)

Сначала создайте новый на тоже поле. Что бы создался - desc добавьте.

А потом уже старый удаляйте.

Обеспечте что бы новый индекс лез в логи без "длинной транзакции" (база ведь с логированием ?). При типичных настройках это значит что сумма всех логов лучше что бы была равна двум размерам операции ((получается 20Г).

Из неожиданного - проверьте что бы место под бэкап этих 10Г логов неожиданно не кончилось :)
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38992170
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Век живи, век учись. Это я по поводу создания второго индекса на том же поле при помощи DESC. Тонко, тонко...
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38992468
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за совет.
Павел, а как отключить логирование при создании индекса?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38993134
Сергей БСпасибо за совет.
Павел, а как отключить логирование при создании индекса?

# LOG_INDEX_BUILDS - Enable (1) or disable (0) index page logging.
# Required for RSS. Optional for HDR and SDS.

Возможно у вас и не включён.

Для изменения параметра требуется перезапуск.

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

Верно: база с логированием - индекс как в LOG_INDEX_BUILDS

У меня-то RSS всегда как бесплатный бэкап включён, по этому LOG_INDEX_BUILDS то же всегда 1.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38993331
cpr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
cpr
Гость
Бэкап ты можешь не любить,
но HADR ты иметь обязан!
Ведь индекс
(быть или не быть)
наш ДБА спасти обязан!
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38993413
Ikir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Яковлев ПавелСергей БСпасибо за совет.
Павел, а как отключить логирование при создании индекса?

# LOG_INDEX_BUILDS - Enable (1) or disable (0) index page logging.
# Required for RSS. Optional for HDR and SDS.

Верно: база с логированием - индекс как в LOG_INDEX_BUILDS


Параметр LOG_INDEX_BUILDS действует для случаев RSS,HDR,SDS.
Автор вроде ничего такого не говорил.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38993859
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще раз спасибо.
БД без RSS,HDR,SDS.
Часто используемый запрос стал выполняться очень долго. Судить, что запрос работает, можно только по onstat –u –r. (поле nreads). Может привести скрин или строку???
Поля reg_paym_dt , reg_date, recv_code , p.pm_state, p.paym_ord проиндексированы.
Update statistic high по всей таблицы сделан.

На всякий случай, таблица фрагментирована по выражению by round robin in. Почти все чанки зеркалируются
Вот запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0



Если запустить запрос без min ( ), то в выборке окажутся св среднем 300000 – 700000 записей и время выполнения около 30 сек
Если время выборки установить в пределах 2-3 часов, запрос тоже отрабатывает быстро (2-3 сек), не зависимо от выбранной даты и месяца.
Следующая конструкция выполняется менее 2 секунд. Нет оператора min ( )
1.

QUERY: (OPTIMIZATION TIMESTAMP: 06-26-2015 14:31:41)
------
SELECT p.reg_date
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0

Estimated Cost: 449280
Estimated # of Rows Returned: 71534

1) informix.p: INDEX PATH

Filters: ((informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 )

(1) Index Name: informix.paym__ix_reg_paym_dt
Index Keys: reg_paym_dt (Serial, fragments: ALL)
Lower Index Filter: informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second
Upper Index Filter: informix.p.reg_paym_dt <= datetime(2015-06-13 23:59:59) year to second


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 81901 71534 464778 00:01.38 449281

2. Создаю по этому запросу темповую таблицу и по ней ищу min (date). Время выполнения менее 2 сек
QUERY: (OPTIMIZATION TIMESTAMP: 06-26-2015 14:36:46)
------
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT p.reg_date 
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0
into temp tmp_r_d;



Estimated Cost: 449280
Estimated # of Rows Returned: 71534

1) informix.p: INDEX PATH

Filters: ((informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 )

(1) Index Name: informix.paym__ix_reg_paym_dt
Index Keys: reg_paym_dt (Serial, fragments: ALL)
Lower Index Filter: informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second
Upper Index Filter: informix.p.reg_paym_dt <= datetime(2015-06-13 23:59:59) year to second


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p
t2 tmp_r_d

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 81901 71534 464778 00:00.80 449281

type table rows_ins time
-----------------------------------
insert t2 81901 00:00.99


QUERY: (OPTIMIZATION TIMESTAMP: 06-26-2015 14:36:47)
------
select min (reg_date) from tmp_r_d;

Estimated Cost: 2946
Estimated # of Rows Returned: 1

1) informix.tmp_r_d: SEQUENTIAL SCAN


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 tmp_r_d

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 81901 81901 81901 00:00.04 2946

type rows_prod est_rows rows_cons time
-------------------------------------------------
group 1 1 81901 00:00.04

3. Делаю запрос с оператором min, но интервал выборки 2 часа

QUERY: (OPTIMIZATION TIMESTAMP: 06-26-2015 14:40:37)
------
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date) 
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 01:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0



Estimated Cost: 9689
Estimated # of Rows Returned: 1

1) informix.p: INDEX PATH

Filters: ((informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 )

(1) Index Name: informix.paym__ix_reg_paym_dt
Index Keys: reg_paym_dt (Serial, fragments: ALL)
Lower Index Filter: informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second
Upper Index Filter: informix.p.reg_paym_dt <= datetime(2015-06-13 01:59:59) year to second


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 2108 5961 8619 00:00.02 9689

type rows_prod est_rows rows_cons time
-------------------------------------------------
group 1 1 2108 00:00.02


5. делаю запрос с min(p.reg_date) за интервал 1 день.
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date) 
FROM paym p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0 



О том, что он не висит видно из команды (колонка nreads)
onstat -r -u | grep 1599044 > /tmp/tmp.log
nreads
182f12df58 ---PR-- 1599044 informix - 0 0 2 6905200 17408
182f12df58 ---PR-- 1599044 informix - 0 0 2 6905920 17408
182f12df58 ---P--- 1599044 informix - 0 0 2 6906576 17408
…………………………………………………………………………………………
182f12df58 B--PR-- 1599044 informix - 19ed5cda0 0 2 7232992 17408
182f12df58 B--PR-- 1599044 informix - 19f61d160 0 2 7233696 17408


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 1 71534 552110204 55:12.79 1059

type rows_prod est_rows rows_cons time
-------------------------------------------------
group 1 1 1 55:12.79


за каким х.. запрос сканирует всю таблицу rows_scan = 552110204
Как отвадить информикс от этого?















Не пойму, почему стало так долго выполняться. Как
Вот план его выполнения
-- execution plan at /home/informix/sqexplain.out at
QUERY: (OPTIMIZATION TIMESTAMP: 06-25-2015 15:04:51)
------
SELECT min (reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'

Estimated Cost: 133
Estimated # of Rows Returned: 1

1) informix.p: INDEX PATH

Filters: (informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second AND informix.p.reg_paym_dt <= datetime(2015-06-13 23:59:59) year to second )

(1) Index Name: informix.paym__ix_reg_date
Index Keys: reg_date (Aggregate) (Serial, fragments: ALL)
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38993948
Ikir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б,

Когда быстро - у вас используется индекс: informix.paym__ix_reg_paym_dt
Когда медленно - informix.paym__ix_reg_date. Наверно он битый.
Попробуйте хинтом выключить индекс informix.paym__ix_reg_date.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38994246
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IkirСергей Б,

Когда быстро - у вас используется индекс: informix.paym__ix_reg_paym_dt
Когда медленно - informix.paym__ix_reg_date. Наверно он битый .
Попробуйте хинтом выключить индекс informix.paym__ix_reg_date.
Причём тут битость индекса?! План выполнения оптимизатор выбирает неэффективно.
Основных вариантов 3:
1. Статистика такова. что не отражает суровую реальность. И есть вариант, что лучше её не соберёшь.
2. Ой, всё.

Независимо от возможности или невозможности решения проблемы со статистикой простым решением является создание индекса
reg_paym_dt, reg_date.
И прочтите хоть что-то про оптимизацию запросов
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38994251
Ikir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойОсновных вариантов 3:
1. Статистика такова. что не отражает суровую реальность. И есть вариант, что лучше её не соберёшь.
2. Ой, всё.


А сообщение пятая строка сверху вас не смущает?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38994273
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IkirАнатоЛойОсновных вариантов 3:
1. Статистика такова. что не отражает суровую реальность. И есть вариант, что лучше её не соберёшь.
2. Ой, всё.


А сообщение пятая строка сверху вас не смущает?
Нет, не смущает. Потому-что статистика не молот Тора. Статистика помогает оптимизатору выбрать оптимальное решение, но не гарантирует его САМА ПО СЕБЕ. Я написал: "есть вариант", но не утверждал, что 100% в данном случае мы на него наткнулись.

Поможет индекс, по двум полям, поможет хинт с указанием выбора нужого индекса или указаним игнорирования ненужного индекса.

А ещё поможет понимание, что оптимизатор для каждого запроса получает (не всегда отображаеиое явно в плане, к сожалению) цель запроса: получить все записи или пользователю достаточно первой.

И у меня ошушение, что настройки сервера или сессии в последнем запросе указывают на получение первой записи. Вот оптимизатор с текущей статистикой и ошибается.....

Так что помочь должно ещё указание оптимизации ALL_ROWS или выгрузка INTO TEMP :)
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38994391
Сергей БЕще раз спасибо.
БД без RSS,HDR,SDS.
Часто используемый запрос стал выполняться очень долго.


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


Согласен.
Первый вариант затратный, но скорее всего и более оптимальный будет с точки зрения быстродействия.
Второй вариант НЕ затратный, пригоден для экспериментов прямо сейчас, но и скорее всего менее оптимальный.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38994978
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за советы. Извините, что так долго не отвечал, база большая. Все делается долго.
Сейчас временно запросы делаются через темповые таблицы
На текущий момент провожу эксперименты на тестовой базе, плюс параллельно на бою .

Бой
Отключил индекс по полю. Время выполнения запроса менее секунды
Код: sql
1.
SELECT {+AVOID_INDEX (plat paym__ix_reg_date)} min (p.reg_date) FROM plat



Бэкап (виртуалка)


На бэкапе (на ругань про ISAM error: no free disk space for sort пока не обращаю внимания) Смотрю индексы paym__ix_reg_date, paym__ix_reg_paym_dt.
Они не «битые»

Запустил на выходные
oncheck -cI ok_arch:plat
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Validating indexes for ok_arch:informix.plat..
                Index paym__ix_reg_paym_dt_n
                  Index  fragment partition pm_dbs1 in DBspace pm_dbs1
    ………………………..
                Index  fragment partition pm_dbs8 in DBspace pm_dbs8
                Index paym_ix_ppnt_tool_dscr
                  Index  fragment partition datadbs2 in DBspace datadbs2
Could not check rowids and perform data<->index check
ISAM error: no free disk space for sort
                Index  754_1846
                  Index  fragment partition pm_inddbs1 in DBspace pm_inddbs1
                Index paym__ix_param0
                  Index  fragment partition pm_inddbs2 in DBspace pm_inddbs2
Could not check rowids and perform data<->index check
ISAM error: no free disk space for sort
……………………………………………..
                Index  fragment partition pm_inddbs5 in DBspace pm_inddbs5        Index paym__ix_reg_date
                Index  fragment partition pm_inddbs5 in DBspace pm_inddbs5        Index paym__ix_reg_paym_dt
…………………………………………..
Please Drop and ReCreate Index paym_ix_ppnt_tool_dscr for ok_arch:informix.plat.
Please Drop and ReCreate Index paym__ix_param0 for ok_arch:informix.plat.



Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0



QUERY: (OPTIMIZATION TIMESTAMP: 06-29-2015 13:33:18)
------
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0



Estimated Cost: 4
Estimated # of Rows Returned: 1

1) informix.p: INDEX PATH

Filters: ((informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 )

(1) Index Name: informix.paym__ix_reg_paym_dt
Index Keys: reg_paym_dt (Serial, fragments: ALL)
Lower Index Filter: informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second
Upper Index Filter: informix.p.reg_paym_dt <= datetime(2015-06-13 23:59:59) year to second


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p

type table rows_prod est_rows rows_scan ti me est_cost
-------------------------------------------------------------------
scan t1 81901 1 464778 00:09.44 5

type rows_prod est_rows rows_cons time
-------------------------------------------------
group 1 1 81901 00:09.53

Создал индекс (не убивая старого, время создания 8 часов)
create index paym__ix_reg_paym_dt_n on .plat (reg_paym_dt desc) online;
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT min(p.reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0




QUERY: (OPTIMIZATION TIMESTAMP: 06-29-2015 08:32:11)
------
SELECT min(p.reg_date)
FROM plat p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt <= '2015-06-13 23:59:59'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0

Estimated Cost: 3
Estimated # of Rows Returned: 1

1) informix.p: INDEX PATH

Filters: ((informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 )

(1) Index Name: informix.paym__ix_reg_paym_dt_n
Index Keys: reg_paym_dt (desc) (Serial, fragments: ALL)
Lower Index Filter: informix.p.reg_paym_dt <= datetime(2015-06-13 23:59:59) year to second
Upper Index Filter: informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second


Query statistics:
-----------------

Table map :
----------------------------
Internal name Table name
----------------------------
t1 p

type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 81901 1 464778 00:23.71 4

type rows_prod est_rows rows_cons time
-------------------------------------------------
group 1 1 81901 00:23.85


Запрос отработал за 23.85 секунды, по старому индексу работает 09.53.
Пока никаких мыслей, что делать с таблицей на бою. Напоминаю, как временный вариант, сейчас запрос работает через временную таблицу
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38995479
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б, надеюсь вы в курсе что время не всегда идеальный показатель производительности. Возможно что индекс по двум полям пока не был востребован, и грузился с диска для вашего запроса, а для индекса по одному полю уже находился в памяти...
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38995634
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойСергей Б, надеюсь вы в курсе что время не всегда идеальный показатель производительности. Возможно что индекс по двум полям пока не был востребован, и грузился с диска для вашего запроса, а для индекса по одному полю уже находился в памяти...
1. Пардон, был недостаточно внимателен. Вышесказанное относится к индексу reg_paym_dt ASC и reg_paym_dt DESC.
2. По поводу моего совета с индексом по (reg_paym_dt, reg_date) забейте, я был неправ - для вашего запроса c фильтрами он не поможет.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38995713
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще раз спасибо за ответы.
АнатоЛой, это запрос работал раньше очень быстро. Мне показали логи, выполнявшие этот запрос и ранее. Просто в какой-то момент времени (пару недель назад, начал «дурить» запрос. На эмоциях я и создал тему, что полетел индекс.
После восстановления бэкапа на тестовой среде (виртуалка) оказалось, что
А) индексы не битые (сейчас проверяю индексы varchar (255,16) когда выдавалось сообщениеno free disk space for sort)
Б) в трейсе на обоих серверах выборка идет по одному и тому же индексу (только на бою работает около часа, а на тестовом сервере пару минут)
В) update statistics high - не помог
Из-за чего это произошло – пока не понятно. И как "вылечить" это тоже ясности нет. Дня через 3 попробую содать индекс как советовал Павел (запрос не массовый).
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996109
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б, как минимум на боевой другая нагрузка, степень загруженности дисков и памяти и степень разнообразности запросов. Проблема на боевом может быть не в этом запросе, он мог и не измениться. Просто выросла нагрузка в другом месте или появилась новая, а именно этот запрос оказался на границе своей производительности и первым обратил на себя внимание. Сравните общую производительности сервера раньше и сейчас.
Смотрите в статистике запросов и сравнивайте dskreads и bufreads.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996114
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б,
пересоздание индекса как советовал Павел требуется, если индекс битый (или если оченььх очется избавиться от такого подозрения).
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996190
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо АнатоЛой.
Будем "копать" в направлении, указанных Вами.
Но в голове пока не укладывается, да и опыта не хватает как такое может быть ("тормоз" на запросе).
Отобрать энное кол-во строк, а из них выбрать одну min (date). Время должно уйти только на сканирование строк в диапазоне.

select min (date) from (select ... into temp) менее 1 сек
SELECT {+AVOID_INDEX (plat paym__ix_reg_date}) min (date) менее 1 сек
SELECT {+INDEX (plat paym__ix_reg_paym_dt)} min (date) менее 1 сек
select min (date) 55 минут
SELECT {+INDEX (plat paym__ix_reg_date)} min (date) 55 минут
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996326
GVF112GVF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей БСпасибо АнатоЛой.
Будем "копать" в направлении, указанных Вами.
Но в голове пока не укладывается, да и опыта не хватает как такое может быть ("тормоз" на запросе).
Отобрать энное кол-во строк, а из них выбрать одну min (date). Время должно уйти только на сканирование строк в диапазоне.

select min (date) from (select ... into temp) менее 1 сек
SELECT {+AVOID_INDEX (plat paym__ix_reg_date}) min (date) менее 1 сек
SELECT {+INDEX (plat paym__ix_reg_paym_dt)} min (date) менее 1 сек
select min (date) 55 минут
SELECT {+INDEX (plat paym__ix_reg_date)} min (date) 55 минут

Можно проверить с помощью ocheck -pI .... число уровней в индексном дереве !!! Какой размер страницы используется для db-пространства в котором создан индекс ?? У Вас индекс вынесен в отдельный dbspace или находится в том же что и таблица ???

С уважением,
Вадим.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996345
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БНо в голове пока не укладывается, да и опыта не хватает как такое может быть ("тормоз" на запросе).

РСУБД не искуственный интеллект, а всего лишь модель. Как её люди построили (разработчики Informix, разработчики БД, разрабочики приложения, администраторы БД, автор запроса) - так и работает. "Ой, всё сложно" :).

Сергей, эта тема обширная.
Если вы хотите быстро решить конкретную проблему - ищите спеца и деньги (хоть бы и в форуме).
Если это не критично по времени, или не настолько, чтобы за это платить деньги и вы спокойно обучаетесь за счёт общения - задавайте более узкие вопросы.

1. Вопрос: "Как так могло случиться?"
Ответ: Туча вариантов. Вы действительно готовы все их сейчас обсуждать? Или ожидаете, что кто-то готов вам их просто так рассказать?!

2. Вопрос: "Почему запрос, где сервер выбрал индекс по reg_date (а не по reg_paym_dt), работает на 4 порядка дольше?...
"Отобрать энное кол-во строк, а из них выбрать одну min (date). Время должно уйти только на сканирование строк в диапазоне."

Ответ:
Потому что в условиях фильтрации нет ограничений по полю reg_date.
min у вас по reg_date, а фильтр у вас по reg_paym_dt.
И при выбранном индексе по reg_date сервер для получения ответа на вопрос вычитывает ВСЮ таблицу.
Кстати: Может у вас reg_date - это reg_paym_dt без времени - так сервер про это не знает :).

3. Вопрос: "Почему сервер выбирает индекса по reg_date, а не по reg_paym_dt?
Ответ: Возможные причины мы уже обсуждали.

Ещё вопросы?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996350
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б, и да тема топика не соответствует реальности. Или тему меняйте, или топик заводите. Главное - чётче ставьте вопросы :).
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996805
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GVF112GVF.
oncheck -pl выдает следующие уровни
Level 0
Level 1
Level 2
Level 3

Размер страницы 16К

Индексы по полям reg_date, reg_paym_dt разнесены в разные dbspace, данные в эти dbspace не входят
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38996927
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо АнатоЛой за ответ.
Решение проблемы по времени не критично, т.к. обходные варианты найдены (хинты или через темповую таблицу)

автор1. Вопрос: "Как так могло случиться?"
Ответ: Туча вариантов. Вы действительно готовы все их сейчас обсуждать? Или ожидаете, что кто-то готов вам их просто так рассказать?!


2. Вопрос: "Почему запрос, где сервер выбрал индекс по reg_date (а не по reg_paym_dt), работает на 4 порядка дольше?...
"Отобрать энное кол-во строк, а из них выбрать одну min (date). Время должно уйти только на сканирование строк в диапазоне."

Ответ:
Потому что в условиях фильтрации нет ограничений по полю reg_date.
min у вас по reg_date, а фильтр у вас по reg_paym_dt.
И при выбранном индексе по reg_date сервер для получения ответа на вопрос вычитывает ВСЮ таблицу.
Кстати: Может у вас reg_date - это reg_paym_dt без времени - так сервер про это не знает :).

1. Не готов и не ожидаю.
2. У меня последний вопрос. Зачем серверу вычитывать всю таблицу, когда я просил его выбрать минимальную дату (пусть и не полю, указанному в условии) из некоторого диапазона выбранных строк.
Раньше он так и работал.
Также. При задании ограничений в 2-3 часа запрос не сканирует всю таблицу.
Прошу «ногами не бить». Если есть предположения, ответьте.

ЗЫ. Тип полей reg_date и reg_paym_dt DATETIME YEAR TO SECOND.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38997237
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б, пардон за мой тон, иногда всё-таки забываю, что мир ВСЕГДА НЕ СОВСЕМ ТАКОЙ, как я о нём думаю :).

Попробую ответить последовательно по всей картинке.

1. По вашему запросу сервер:
1.1) смотрит в кеше запросов, нет ли "такого же" запроса;
1.2) если нет, то составляет план запроса (исходя из статистики, а не реального количества строк) и сохраняет план запроса в кеш;
Статистика "отражает" реальную картину, но она "сжата с потерями";
1.3) по выбранному плану делает выборку данных.

В итоге при составлении плана данного запроса сервер фактически выбирает между двумя вариантами на основании статистики:
1.а) используя индекс по reg_paym_dt, перебрать все строки, где reg_paym_dt попадает в указанный период (обозначим количество строк X ). При этом трудоёмкость варианта "а" оценивается как: что стоит найти минимальный элемент в неупорядоченном по reg_date массиве в X(если верить статистике) элементов).
1.б) используя индекс reg_date перебирать строки от min(reg_date) до max(reg_date), пока не попадётся строка, в которой reg_paym_dt попадает в указанный в фильтре диапазон. При этом трудоёмкость варианта "б" оценивается как: сколько при таком подходе в среднем (если верить статистике) придётся прочитать строк, чтобы среди них попалась первая строка с подходящим reg_paym_dt - обозначим количество строк Y .

В зависимости от конкретных значений фильтра по reg_paym_dt на основании получившихся X и Y сервер и выбирает тот вариант, где его трудоёмкость "кажется" меньшей.

Может возникнуть ощущение, что вариант (а) ВСЕГДА лучше, и вы захотите сервер принудительно выбирать индекс по reg_paym_dt.
Это не так. Укажите в запросе диапазон для reg_paym_dt "от царя Гороха и до взрыва Солнца", и
- по варианту (а) серверу придётся вычитать все строки таблицы, поскольку все строки соответствуют условию по reg_paym_dt;
- по варианту (б) серверу придётся прочитать всего одну строку: reg_date у неё минимальный даже по всей таблице, и reg_paym_dt уже соответствует указанному фильтру.

2. Мы сейчас видим:
2.1) сервер для запроса "SELECT min(reg_date) FROM plat WHERE reg_paym_dt попадает в диапазон за конкретный день"
почему-то выбирает индекс по полю reg_date, а не индекс по полю reg_paym_dt
2.2) убедились, что если таки заставить сервер выбирать индекс по reg_paym_dt, запрос для наших примеров выполняется более эффективно.

3. Вопрос : "Зачем серверу вычитывать всю таблицу, когда я просил его выбрать минимальную дату (пусть и не полю, указанному в условии) из некоторого диапазона выбранных строк."

Ответ :

Если сервер к шагу 1.3) таки выбрал план запроса (а), то серверу уже ничего особо не остаётся.

Либо вы хорошо понимаете, как правильно "читать" план выполнения запроса, но невнимательно в него смотрели,
либо вы плохо понимаете работу механизма выборки данных по уже выбранному плану запроса.

Подозреваю, что скорее второе, поэтому ещё раз разъясняю:

Сервер, следуя уже выбранному плану запроса с индексом по reg_date:
- перебирает строки всей таблицы в порядке индекса по reg_date, начиная со строки с минимальным reg_date.
обратите внимание, у сервера нет другой информации (ограничений) по полю reg_date в запросе.
;
- останавливается, когда наткнётся на строку, в которой reg_paym_dt попадает в указанный в запросе диапазон.

При этом, чем больше разница между mіn(reg_date) и указанным минимальным значением в диапазоне для reg_paym_dt, тем больше и дольше сервер будет перебирать строки таблицы. В худшем случае - практически всю таблицу.

4. Вопрос : "При задании ограничений в 2-3 часа запрос не сканирует всю таблицу."
Ответ : потому что на этапах 1.1)-1.2) сервер выбрал индекс по полю reg_paym_dt, который и в реальности оказался более эффективен.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38997278
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БЗачем серверу вычитывать всю таблицу, когда я просил его выбрать минимальную дату (пусть и не полю, указанному в условии) из некоторого диапазона выбранных строк.
Раньше он так и работал.
Также. При задании ограничений в 2-3 часа запрос не сканирует всю таблицу.
Прошу «ногами не бить». Если есть предположения, ответьте.

Предположения:

Первое:
раньше вы тоже пробовали запускать запрос с фильтром за целый день и больше? Если да, использовали ли вы раньше фильтр за последние дни?

Второе:
не поменялся ли принцип сбора статистики: который был раньше, и который вы имеете сейчас.

Третье:
понимаете ли вы, что просто "UPDATE STATISTICS HIGH" :
а) это не идеальная статистика, особенно для вашего случая;
б) имеет ещё параметры;

Четвёртое:
вы можете заставить сервер работать лучше, если не будете ему сами указывать индексы,
а сможете ему "рассказать", как "связаны" reg_date и reg_paym_dt.
Ведь они как-то связаны, правда?
Ну, например,:
а) reg_date >=reg_paym_dt
б) reg_paym_dt >=reg_date
в) ABS(reg_paym_dt - reg_date) < 1 месяца
г) ...
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38997280
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Б
ЗЫ. Тип полей reg_date и reg_paym_dt DATETIME YEAR TO SECOND.
Если бы вы сразу дали DDL или мы сразу его попросили, процесс бы двигался ещё эффективнее.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38997287
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойПредположения:
...



Пятое: не поменялся ли заметно объём БД с того момента, как "раньше оно так и работало".

Шестое: не поменялись ли настройки сервера за этот период, которые могли повлиять на выбор оптимизатора.

Седьмое и последнее: определитесь что из списка для вас важнее понять:
- как оно так случилось: раньше хорошо, теперь плохо;
- почему оно так работает, как работает сейчас;
- как сделать, чтобы работало хорошо.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998167
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо ОГРОМНОЕ. Ваш первый ответ (за 01/07/15) открыл мне много того, о чем я представления не имел.

авторПредположения:

Первое:
раньше вы тоже пробовали запускать запрос с фильтром за целый день и больше? Если да, использовали ли вы раньше фильтр за последние дни?

Второе:
не поменялся ли принцип сбора статистики: который был раньше, и который вы имеете сейчас.

Третье:
понимаете ли вы, что просто "UPDATE STATISTICS HIGH" :
а) это не идеальная статистика, особенно для вашего случая;
б) имеет ещё параметры;

Четвёртое:
вы можете заставить сервер работать лучше, если не будете ему сами указывать индексы,
а сможете ему "рассказать", как "связаны" reg_date и reg_paym_dt.
Ведь они как-то связаны, правда?
Ну, например,:
а) reg_date >=reg_paym_dt
б) reg_paym_dt >=reg_date
в) ABS(reg_paym_dt - reg_date) < 1 месяца
г) ...
Пятое: не поменялся ли заметно объём БД с того момента, как "раньше оно так и работало".

Шестое: не поменялись ли настройки сервера за этот период, которые могли повлиять на выбор оптимизатора.

Седьмое и последнее: определитесь что из списка для вас важнее понять:
- как оно так случилось: раньше хорошо, теперь плохо;
- почему оно так работает, как работает сейчас;
- как сделать, чтобы работало хорошо.

Первое.
запрос запускается только за день, даты в основном (95%) предыдущий месяц. Запросов может быть 1-31
Второе.
Работает крон 1 раз в неделю (update statistics medium from table ..)
HIGHT запустил в ручную 1 только раз скриптом, что выдал Server Studio (сначала LOW, Hight,Medium)
Третье.
Понимаю. Буду досконально разбираться.

Четвертое.
p.reg_paym_dt >= p.reg_date. Запустил запрос с этим условием. Лучше не стало.

Код: sql
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.
QUERY: (OPTIMIZATION TIMESTAMP: 07-02-2015 15:30:58)
------
SELECT min(p.reg_date) --81901 
FROM paym p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt < '2015-06-14 00:00:00'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0
and p.reg_paym_dt >= p.reg_date;

Estimated Cost: 3998
Estimated # of Rows Returned: 1

  1) informix.p: INDEX PATH

        Filters: (((((informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second AND informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )) AND informix.p.reg_paym_dt >= informix.p.reg_date ) AND informix.p.reg_paym_dt < datetime(2015-06-14 00:00:00) year to second ) AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 ) 

    (1) Index Name: informix.paym__ix_reg_date
        Index Keys: reg_date   (Aggregate)  (Serial, fragments: ALL)


Query statistics:
-----------------

  Table map :
  ----------------------------
  Internal name     Table name
  ----------------------------
  t1                p

  type     table  rows_prod  est_rows  rows_scan  time       est_cost
  -------------------------------------------------------------------
  scan     t1     1          19011     545457314  50:47.02   3999    

  type     rows_prod  est_rows  rows_cons  time
  -------------------------------------------------
  group    1          1         1          50:47.02




Пятое.
Сама БД растет (с начала года на 4 Гб), но таблица по которой делается выборка, практически не меняется. С одним но. Данные вставляются сотнями тысяч и сотнями тысяч удаляются. Кол-во строк на любой день может как прибавиться, так и убавиться.

Шестое.
Нет. Ежедневно копируется onconfig и добавляется к архиву (сравнил, параметры за последние 2 месяца не менялись).

Седьмое.
- как оно так случилось: раньше хорошо, теперь плохо;


А можно еще вопрос, не относящийся к этому топику?

Есть таблица, rowsize 5498. Она находится в dbspce, у которой pagesize равна 4096. Как будут 2 строки заполнять страницу. Одна полная и остаток + одна полная и остаток
или
две полных и остатки заполнят одну страницу?
Извините за назойливость.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998339
bk0010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отмечусь на память.
ИМХО одна запись загадит 2 страницы. Вариант со сжатием не рассматриваем?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998478
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БПервое:
раньше вы тоже пробовали запускать запрос с фильтром за целый день и больше? Если да, использовали ли вы раньше фильтр за последние дни?

запрос запускается только за день, даты в основном (95%) предыдущий месяц. Запросов может быть 1-31
[/quot]
А остальные 5%? Можете расшифровать смысл реквизитов запроса и результата запроса/запросов?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998479
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извините, слетело, вот так лучше:

Сергей БАнатоЛойПервое:
раньше вы тоже пробовали запускать запрос с фильтром за целый день и больше? Если да, использовали ли вы раньше фильтр за последние дни?

запрос запускается только за день, даты в основном (95%) предыдущий месяц. Запросов может быть 1-31

А остальные 5%? Можете расшифровать смысл реквизитов и запроса/запросов?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998481
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БАнатоЛойВторое:
не поменялся ли принцип сбора статистики: который был раньше, и который вы имеете сейчас.

Работает крон 1 раз в неделю (update statistics medium from table ..)
HIGH запустил вручную 1 только раз скриптом, что выдал Server Studio (сначала LOW, High,Medium)

Уточните,
- HIGH вручную вы запустили ДО первых проблем с запросом или после?
- зачем запускали?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998493
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БАнатоЛойЧетвёртое:
вы можете заставить сервер работать лучше, если не будете ему сами указывать индексы,
а сможете ему "рассказать", как "связаны" reg_date и reg_paym_dt.
Ведь они как-то связаны, правда?
Ну, например,:
а) reg_date >=reg_paym_dt
б) reg_paym_dt >=reg_date
в) ABS(reg_paym_dt - reg_date) < 1 месяца
г) ...

p.reg_paym_dt >= p.reg_date. Запустил запрос с этим условием. Лучше не стало.

SQL
Код: sql
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.
QUERY: (OPTIMIZATION TIMESTAMP: 07-02-2015 15:30:58)
------
SELECT min(p.reg_date) --81901 
FROM paym p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt < '2015-06-14 00:00:00'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0
and p.reg_paym_dt >= p.reg_date;

Estimated Cost: 3998
Estimated # of Rows Returned: 1

  1) informix.p: INDEX PATH

        Filters: (((((informix.p.reg_paym_dt >= datetime(2015-06-13 00:00:00) year to second AND informix.p.recv_code IN (110 , 101 , 510 , 810 , 403 , 72101 , 11101 )) AND informix.p.reg_paym_dt >= informix.p.reg_date ) AND informix.p.reg_paym_dt < datetime(2015-06-14 00:00:00) year to second ) AND informix.p.pm_state = 3 ) AND informix.p.paym_ord > 0 ) 

    (1) Index Name: informix.paym__ix_reg_date
        Index Keys: reg_date   (Aggregate)  (Serial, fragments: ALL)


Query statistics:
-----------------

  Table map :
  ----------------------------
  Internal name     Table name
  ----------------------------
  t1                p

  type     table  rows_prod  est_rows  rows_scan  time       est_cost
  -------------------------------------------------------------------
  scan     t1     1          19011     545457314  50:47.02   3999    

  type     rows_prod  est_rows  rows_cons  time
  -------------------------------------------------
  group    1          1         1          50:47.02




1. Я недостаточно точно изложил свою мысль. Я не просил добавить условие в запрос.
Я хотел узнать смысл реквизитов и нет ли в учёте каких-то внешних ограничений, которые сейчас никак не отражены в схеме БД.
Если такие зависимости есть, то зная их, может быть получится так изменить DDL или сам запрос, что оптимизатор будет корректнее выбирать план.
Например, если p.reg_paym_dt >= p.reg_date, то в запрос можно добавить новое условие:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT min(p.reg_date)
FROM paym p
WHERE p.reg_paym_dt >= '2015-06-13 00:00:00'
AND p.reg_paym_dt < '2015-06-14 00:00:00'
AND p.recv_code in (110,101,510,810,403,72101,11101)
AND p.pm_state = 3
AND p.paym_ord > 0
and p.reg_date < '2015-06-14 00:00:00';


Поможет ли при текущей статистике это оптимизатору, сейчас размышлять времени не имею.

2. При выполнении запроса поначалу можно его запускать с хинтом
{+EXPLAIN, AVOID_EXECUTE} (см. тут ). План запроса будет выбран, но сам запрос не будет запущен. Очень экономит время при проверке гипотез "а как поведёт себя вот такой запрос в реальности" :).
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998496
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БАнатоЛойПятое: не поменялся ли заметно объём БД с того момента, как "раньше оно так и работало".

Сама БД растет (с начала года на 4 Гб), но таблица по которой делается выборка, практически не меняется. С одним но. Данные вставляются сотнями тысяч и сотнями тысяч удаляются. Кол-во строк на любой день может как прибавиться, так и убавиться.

Это существенное уточнение. Я так понимаю, такое удаление и вставка происходит разы в день.
А статистика ПОСЛЕ таких вставок и удалений обновляется сразу?
И какие характеристики пакетов на удаление и вставку? А-ля, "перезалей все записи у которых reg_paym_dt = сегодня или вчера?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998498
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БАнатоЛойСедьмое и последнее: определитесь что из списка для вас важнее понять:
- как оно так случилось: раньше хорошо, теперь плохо;
- почему оно так работает, как работает сейчас;
- как сделать, чтобы работало хорошо.

- как оно так случилось: раньше хорошо, теперь плохо;

В таком случае поиск вопроса без оплаты услуг затянется на недели :).
Нужно ДО ЧЕРТА инфы и специалист "на месте".
Если вообще ответ будет найден.

Странный у вас бизнес: "поиск виновных" вместо "повышаем компетентность и достигаем результатов". Вы выбираете гораздо более длинный путь поиска ответа, и получите гораздо меньший опыт, чем при выборе третьего, или хотя бы второго варианта :).
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998507
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БА можно еще вопрос, не относящийся к этому топику?

Можно, кто ж вам запретит, но рекомендую в следующий раз стартовать другой :).

Сергей БЕсть таблица, rowsize 5498. Она находится в dbspce, у которой pagesize равна 4096. Как будут 2 строки заполнять страницу. Одна полная и остаток + одна полная и остаток
или
две полных и остатки заполнят одну страницу?


Не помню, менялась ли концепция, но с одной стороны в 12.10 остатки строк и просто строки могут жить на одной странице :
дока 12.101. After the database server creates a remainder page to accommodate a long row, it can use the remaining space in this page to store other rows.

, а с другой стороны :

дока 12.102. A page is considered full when the count of free bytes is less than the number of bytes needed to store a row of maximum size.
.
Одна страница принадлежит экстенту, который принадлежит таблице.
То есть на одной странице или часть большой строки, или одна строка, или несколько строк одной и той же таблицы.

Если большая строка не влезла на одну страницу, то максимальный размер строки такой таблицы больше чем одна страница.
А значит, что свободное место на странице с остатком большой строки меньше, чем максимальный размер строки в этой таблице.
Значит, согласно (2) такая страница будет сразу помечена как "полностью заполненная".

Но для чего тогда написано (1)?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998525
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И теперь всё-таки по поводу
АнатоЛой- как сделать, чтобы работало хорошо.


Итак, у вас есть 95% запросов, для которых из имеющихся индексов индекс по (reg_paym_dt) - идеал.
Используйте сознательно хинт для этих 95% - и не парьтесь. :)

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

Варианты А. Используем знания, про которые мы знаем, что вы знаете :)
Вариант А1. Создайте индекс ind_a1 (reg_paym_dt, reg_date).
Если сервер выбирает такой индекс, он в массиве X будет перебирать строки в порядке, повышающем вероятность успеха: остановиться на первой найденной строке, а не стопудово считывать строки всего массива X.

Вариант А2. Создайте индекс ind_a2 (reg_date, reg_paym_dt).
Даже если сервер выбирает такой индекс и "перебирает всю таблицу", он будет считывать не "все" строки таблицы, а "все" ключи индекса, а на диск полезет только за теми строками, которые попадали у нас в массив X.
То есть: не паримся с причинами метаний оптимизатора, а уменьшаем дисковый ввод/вывод с "читаем все строки " до "читаем весь индекс "+"строки только массива X". И есть предположение, что для вас это - на три порядка быстрее.



Варианты Б. Используем знания, про которые мы НЕ знаем, знаете ли вы :)

Вы часто запускаете запросы с выражением фильтра по диапазону "reg_paym_dt >= первая секунда суток AND reg_paym_dt < последняя секунда следующих суток".
А фактически это выражение записывается точным равенством : DATE(reg_paym_dt) = MDY(x,y,z).

Попробуйте добавить специально под данный тип запросов ещё два индекса (с использованием функций):
- индекс ind_b1 по двум значениям - (DATE(reg_paym_dt), reg_date);
- индекс ind_b2 по двум значениям - (reg_date, DATE(reg_paym_dt));

и в запросе использовать приведённое выше точное равенство вместо диапазона.

По аналогии с вариантами А1 и А2:

Вариант B1. При выборе ind_b1 для запроса за день сервак повысит вероятность найти нужную строку: он будет перебирать не все X строк,
а приблизительно в 2 раза меньше, потому что может позволить себе остановиться на первой же строке, которая подойдёт под остальные условия фильтра.

Вариант B2. При выборе ind_b2 сервер не считывая всё строку, а только по значениям ключа индекса поймёт, подходит ли эта строка по значению DATE(reg_paym_dt).



Варианты B против вариантов А улучшит реальное выполнение приблизительно в (8+8)/(4+8)=1,3 раза за счёт размера ключа индекса.

Кроме того, если поля recv_code и/или pm_state добавляют селективности запросам (заметно уменьшают количество строк в массиве X), можно было бы и их добавить в индексы...
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #38998528
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойВы часто запускаете запросы с выражением фильтра по диапазону "reg_paym_dt >= первая секунда суток AND reg_paym_dt < последняя секунда следующих суток".
Я опечатался, правильно:
"reg_paym_dt >= первая секунда суток AND reg_paym_dt < первая секунда следующих суток".
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #39000477
DrGonzo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select min (date) from (select ... into temp) менее 1 сек
SELECT {+AVOID_INDEX (plat paym__ix_reg_date}) min (date) менее 1 сек
SELECT {+INDEX (plat paym__ix_reg_paym_dt)} min (date) менее 1 сек
select min (date) 55 минут
SELECT {+INDEX (plat paym__ix_reg_date)} min (date) 55 минут

Извиняюсь, не следил за всем топиком, ниже просто размышления на тему. Не судите строго.

Подезреваю, что такой результат может быть, если есть проблема с b-tree cleaner. При удалении/апдейте - ключ индекса помечается delete-флагом, но никуда не исчезает. Удаление таких ключей - задача нити b-tree cleaner. Кажется в 11.50 был баг, при котором нить могла долго крутиться, но ничего чистить.

Если у вас не key-only scan в запросе (запрос только по полю индекса), оптимизатор в том числе учитывает затраты на ввод-вывод - суммирует сколько страниц придется предположительно прочитать из индекса и из tblspace самой таблицы. Возможна ситуация, когда сканирование таблицы без использования индекса потребует чтения меньшего количества страниц, чем если в плане запроса используется индекс. Оптимизатор достаточно умен, чтобы индекс в таком случае не использовать.

Короче, возможно индекс "медленный", т.к. большой и грязный. Проверить можно несколькими способами:

1) Косвенно. Запустить key-only запросы по обоим (медленному и быстрому индексах) и сравнить время выполнения.
2) Зная fillfactor, количество записей в таблице, длину поля по которому строился индекс и размер страницы dbspace в котором он лежит, можно рассчитать количество страниц на каждом уровне индекса и, как следствие, его примерный размер. Это должно коррелировать с выводом 'oncheck -pT' для индекса. Формула кажется была в документации где-то.
3) Можно посмотреть эффективность работы b-tree cleaner в 'onstat -C' - если там совсем маленькие числа, есть повод задуматься.
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #39000493
DrGonzo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это естественно, если статистика свежая и адекватная.

Собственно desc индекс должен отличаться только направлением сортировки, верно ведь? Существенной разницы во времени работы запроса быть не должно. Может есть большие расхождения по размеру в сравнении с исходным?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #39024978
Сергей Б
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСергей Б

Первое:
раньше вы тоже пробовали запускать запрос с фильтром за целый день и больше? Если да, использовали ли вы раньше фильтр за последние дни?


запрос запускается только за день, даты в основном (95%) предыдущий месяц. Запросов может быть 1-31

А остальные 5%? Можете расшифровать смысл реквизитов запроса и результата запроса/запросов? [/quote]

Смысл таков.
Если между организациями не идут остатки, то по запросу создается отчет, в который входят все документы с датой исполнения с .. по .. за каждый день. В шапку отчета включается дата min(reg_date). По поводу дат, reg_date - дата регистрации, reg_date_dt дата исполнения. Почти всегда эти даты равны, но могут иметь расхождения. Например: пришла транзакция, по которой необходимо проверить корректность реквизитов. Для этого делается запрос на сервер, который гарантирует корректность (еще одна организация). А этот сервер «лежит/выстроилась большая очередь».


автор Уточните,
- HIGH вручную вы запустили ДО первых проблем с запросом или после?
- зачем запускали?

Update statistics запускал после появления проблемы.
Т.к. Update statistics по этой таблице запускается раз в неделю в режиме medium, решил пересобрать статистику (а вдруг из-за этого)


автор2. При выполнении запроса поначалу можно его запускать с хинтом
{+EXPLAIN, AVOID_EXECUTE} (см. тут). План запроса будет выбран, но сам запрос не будет запущен. Очень экономит время при проверке гипотез "а как поведёт себя вот такой запрос в реальности" :).

Спасибо. Про это не знал.


авторСтранный у вас бизнес: "поиск виновных" вместо "повышаем компетентность и достигаем результатов". Вы выбираете гораздо более длинный путь поиска ответа, и получите гораздо меньший опыт, чем при выборе третьего, или хотя бы второго варианта :).

Я выясняю причину случившегося ТОЛЬКО ДЛЯ СЕБЯ (кстати, от Ваших ответов я много нового для себя открыл). А приложение давно подправлено и работает быстро.




авторПятое: не поменялся ли заметно объём БД с того момента, как "раньше оно так и работало".

Сама БД растет (с начала года на 4 Гб), но таблица по которой делается выборка, практически не меняется. С одним но. Данные вставляются сотнями тысяч и сотнями тысяч удаляются. Кол-во строк на любой день может как прибавиться, так и убавиться.

Это существенное уточнение. Я так понимаю, такое удаление и вставка происходит разы в день.
А статистика ПОСЛЕ таких вставок и удалений обновляется сразу?
И какие характеристики пакетов на удаление и вставку? А-ля, "перезалей все записи у которых reg_paym_dt = сегодня или вчера?

Данные вставляются в эту таблицу постоянно с периодичностью 5 минут. Ночью запускается процедура, которая просматривает записи на сервере А по такой же таблице за прошедший день и если такая запись есть на сервере «Б» (это наш случай), то делает апдейт всей строки. Если строки нет, делает вставку.
Удаление. Выбираются данные за один день - «текущий день» минус энное количество дней. Данные копируются на сервер «В», а скопированные строки удаляются. Статистика по этой таблице выполняется один раз в неделю в режиме МЕДИУМ.



авторИ теперь всё-таки по поводу

- как сделать, чтобы работало хорошо.
Итак, у вас есть 95% запросов, для которых из имеющихся индексов индекс по (reg_paym_dt) - идеал.
Используйте сознательно хинт для этих 95% - и не парьтесь. :)

Но если:
- есть возможность добавлять индексы;
- есть осознание, что новый индекс сам по себе доп.нагрузка, но минусов от добавления конкретного индекса меньше чем плюсов;
- есть желание узнать новое и доскональнее попрактиковаться в вопросах оптимизации,
то предлагаю следующие варианты;
+ Варианты А. Используем знания, про которые мы знаем, что вы знаете :)



+ Варианты Б. Используем знания, про которые мы НЕ знаем, знаете ли вы :)




Варианты B против вариантов А улучшит реальное выполнение приблизительно в (8+8)/(4+8)=1,3 раза за счёт размера ключа индекса.

Кроме того, если поля recv_code и/или pm_state добавляют селективности запросам (заметно уменьшают количество строк в массиве X), можно было бы и их добавить в индексы...

Про вариант Б. Его я не знал, спасибо.
Вариант А1 не помог.
Вариант А2 и Б - пробую
АнатоЛой, а есть предположения, почему все так стало?
...
Рейтинг: 0 / 0
Сыпанулся индекс на фрагментированной таблице
    #39025262
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей БАнатоЛой, а есть предположения, почему все так стало?

Если здание построено с огрехами, "любой дятел разрушит эту цивилизацию".

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

В вашей власти:
- либо поменять "если",
- либо повысить оптимальность выбираемого сервером решения.

Предположения "почему так случилось" слишком зависят от данных, а не от структур их хранения и обработки.
Гадать в такой ситуации - пальцем в небо, и перебор возможных вариантов неэффективен.
А если ещё и мотив для поиска причин - "найти виноватого" - мне это тем более неинтересно...

Князь КропоткинЕсли часовой вздумает стрелять, то тут ничего не поделаешь. Это - вне нашего предвиденья. Ввиду неизбежной смерти в тюрьме - стоит рискнуть (бежать).
Предлагаю забить на поиски причин, почему часовой мог вздумать стрелять :). Это в прошлом, а причина возможной смерти - в факте попадания в тюрьму...
...
Рейтинг: 0 / 0
51 сообщений из 51, показаны все 3 страниц
Форумы / Informix [игнор отключен] [закрыт для гостей] / Сыпанулся индекс на фрагментированной таблице
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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