#sql #performance #oracle11g
Вопрос:
Что я должен проверить, почему серверу Oracle требуется более 20 секунд, чтобы вернуть UNIQUE
ошибку нарушения ограничений для определенных данных?
Один из наших процессов обрабатывает более 30000 данных в день с помощью нескольких процессов, и некоторое время получает УНИКАЛЬНУЮ ошибку нарушения ограничений за 1 секунду
но для возврата UNIQUE
ошибки нарушения ограничений для конкретных данных требуется более 20 секунд.
Запрос такой же, как показано ниже. (Изменено только имя таблицы)
MERGE INTO TableA S USING ( SELECT NVL(:sccm_cd , ' ') SCCM_CD , NVL(:oder_dt , ' ') ODER_DT , NVL(:mrkt_dstn_cd, ' ') MRKT_DSTN_CD , NVL(:oder_no , ' ') ODER_NO , NVL(:cncd_unpr , 0) CNCD_UNPR , B.SLBY_FEE_GRD_CD , B.ACCT_MNGR_EMPL_NO , C.AO_FEE_GRD_CD FROM DUAL A , TableB B , TableC C WHERE 1 = 1 AND B.SCCM_CD = :sccm_cd AND B.ACNO = :acno AND C.SCCM_CD( ) = B.SCCM_CD AND C.EMPL_NO( ) = B.ACCT_MNGR_EMPL_NO ) T ON ( S.sccm_cd = T.sccm_cd AND S.oder_dt = T.oder_dt AND S.mrkt_dstn_cd = T.mrkt_dstn_cd AND S.oder_no = T.oder_no AND S.cncd_unpr = T.cncd_unpr ) WHEN MATCHED THEN UPDATE SET S.cncd_qty = S.cncd_qty NVL(:cncd_qty ,0) , S.slby_fee = S.slby_fee NVL(:slby_fee ,0) , S.slby_fee_srtx = S.slby_fee_srtx NVL(:slby_fee_srtx,0) , S.idx_fee_amt = S.idx_fee_amt NVL(:idx_fee_amt ,0) , S.cltr_fee = S.cltr_fee NVL(:cltr_fee ,0) , S.trtx = S.trtx NVL(:trtx ,0) , S.otc_fee = S.otc_fee NVL(:otc_fee ,0) , S.wht_fee = S.wht_fee NVL(:wht_fee ,0) WHEN NOT MATCHED THEN INSERT ( sccm_cd , oder_dt , mrkt_dstn_cd , oder_no , cncd_unpr , acno , item_cd , slby_dstn_cd , md_dstn_cd , cncd_qty , stlm_dt , trtx_txtn_dstn_cd , proc_cmpl_dstn_cd , item_dstn_cd , slby_fee_grd_cd , slby_fee , slby_fee_srtx , idx_fee_amt , cltr_fee , trtx , wht_fee , otc_fee , acct_mngr_empl_no , ao_fee_grd_cd ) VALUES ( T.sccm_cd , T.oder_dt , T.mrkt_dstn_cd , T.oder_no , T.cncd_unpr , :acno , :item_cd , :slby_dstn_cd , :md_dstn_cd , NVL(:cncd_qty ,0) , DECODE(:mrkt_dstn_cd, 'TN', T.oder_dt, :stlm_dt) , :trtx_txtn_dstn_cd , '0' , :item_dstn_cd , NVL(:slby_fee_grd_cd, T.SLBY_FEE_GRD_CD) , NVL(:slby_fee ,0) , NVL(:slby_fee_srtx ,0) , NVL(:idx_fee_amt ,0) , NVL(:cltr_fee ,0) , NVL(:trtx ,0) , NVL(:wht_fee , 0) , NVL(:otc_fee , 0) , T.acct_mngr_empl_no , T.ao_fee_grd_cd )
Комментарии:
1. Я не уверен, что понимаю, что здесь измеряют «1 секунда» и «20 секунд». Время между отправкой клиентом
merge
инструкции в базу данных и временем, когда база данных отвечает с уникальной ошибкой нарушения ограничений? Если да, то чего ожидает сеанс в течение этого периода времени? Я предполагаю, что сеанс заблокирован в ожидании другого сеанса, который заблокировал строку, которую он пытается обновить, и требуется 20 секунд, чтобы этот другой сеанс зафиксировал или откатил свои изменения.2. Когда это займет больше времени, я бы предположил, что у вас есть цепочка сеансов, каждый из которых заблокирован другим (т. Е. A заблокирован B заблокирован C заблокирован D), для разрешения которой требуется больше времени.
3. @JustinCave ах…. Я получил это, я тщательно проверю это, основываясь на ваших советах 🙂 Спасибо
Ответ №1:
Для этого может быть несколько причин. Я перечислю здесь некоторые из возможных причин такого поведения.
Проблема параллелизма
insert
Возможно, вы ждете других операций, таких как другие вставки, обновления или удаления.
Проблемы с сетью
Возможно, по какой-то причине ваша сеть перегружена запросами или, если сервер удален, это также может быть проблемой со скоростью Интернета.
Загрузка сервера
Сервер может быть перегружен множеством заданий, которые нужно выполнить.
Медленный запрос
Также возможно, что select
вы используете в своей insert
команде очень медленный. Имело бы смысл проверить его скорость. Кроме того, имело бы смысл insert
также проверить скорость.