Oracle Database 11g Release 11.2.0.2.0 - 64bit Production/ を実行しています。
user、user_learning、および user_group テーブル間の結合である次のクエリがあります。
select u.user_id, u.first_name, u.surname, u.client_company_id, u.username,
ul.completion_status
from user u, user_learning ul
where
u.user_id = ul.user_id (+)
and (ul.enrolment_status = 'E' or ul.enrolment_status is null)
and upper(u.surname) like 'CART%'
and ((u.user_id is not null and (u.client_company_id in ('ABCDEF') )
and exists (select 1
from user_group g
where g.user_id = u.user_id
and g.group_id in
(215479,215480,221934,39901,45709,45710,45712,
45713,45714,45715,45716,45717,45718)
)
)
or (u.user_id = 1209289 or u.manager_id = 1209289)
)
order by u.client_company_id, u.surname, u.first_name, u.user_id;
このクエリは、交互に実行されるたびに 0 の結果と 198 を返し、時には 0 などを返します。
テーブルとこれまでに試したことに関する背景情報
-- Gives 1184415 records
select count(1) from user;
-- Gives 7789332 records
select count(1) from user_learning;
-- Gives 3278032
select count(1) from user_group;
次のように、user テーブルの列 surname にインデックスがあります。
私たちが気づいたことは、IDX_USER_UPPER インデックスを削除してクエリを実行すると、結果が常に一貫していることです。しかし、インデックスを持つということは、しばらくすると結果が同じではないことを意味します。インデックスに疑いがあり、それを削除してクエリを実行すると一貫した結果が得られたように見えましたが、それはしばらくするとクエリが一貫した結果を返さなくなりました。'CART%' のようなアッパー (u.surname) を 'CAR%' や 'CARTE%' などに変更します...その後、0 以上のレコードなどを与える奇妙な動作をゆっくりと開始します.
説明計画は、インデックスが使用される場合と使用されない場合があることを示しています..おそらく、このインデックスは問題ではありません...??
インデックスの統計を収集し、インデックスを再構築しようとしました
CREATE INDEX IDX_USER_UPPER ON USER (UPPER("SURNAME"))
alter index IDX_USER_UPPER compute statistics
alter index IDX_USER_UPPER rebuild
以下も実行しましたが、インデックスが削除された場合を除いて同じ効果があり、しばらくは機能しているようです。
exec DBMS_STATS.gather_table_stats('SCHEMA', 'USER');
exec DBMS_STATS.gather_table_stats('SCHEMA', 'USER_LEARNING');
exec DBMS_STATS.gather_table_stats('SCHEMA', 'USER_GROUP');
exec DBMS_STATS.GATHER_INDEX_STATS ( 'SCHEMA', 'IDX_USER_UPPER');
-- note SCHEMA is our schema name
-- indicates Last_analysed is updated ...
select table_name, owner, to_char(last_analyzed, 'dd-mon-yyyy hh24:mi:ss')
from dba_tables
where table_name IN ('USER', 'USER_LEARNING', 'USER_GROUP')
私が試した別のオプションは、次のように「_no_or_expansion」フラグを設定することです。
alter session set "_no_or_expansion"=true;
-- no impact to the query though
(インデックスが削除されたときに、「CAR%」、「CART%」、「CARTE%」、「CARTER%」がクエリされたときに、クエリが一貫したデータを返し続けるように見えることがあります-奇妙な)
それでも奇妙な動作が存在します。考え、質問、または解決策があります。これに似たものに遭遇した人は、どうぞ。
select * from dba_autotask_client を実行すると、
自動オプティマイザの統計収集 が有効になっていることが表示されます