2016-06-24 1 views
0

Oracle Database 11g Enterprise Editionリリース11.2.0.4.0 - 64bit Productionでこの問合せが発生しました(、50行を3.859秒でフェッチしました。)。それを最適化するには! t_operationには12610行しかありません!問合せの実行が極端に遅い

CREATE OR REPLACE FORCE VIEW "IOT"."V_DEVICES_LIST" ("PRODUCT", "DEVICE_LIST") AS 
select 
    PRODUCT , 
    RTRIM(XMLAGG(XMLELEMENT(E, NAME,', ').EXTRACT('//text()') ).GetClobVal(),',') AS DEVICE_LIST 
from 
    t_operation 
where 
    discriminator = 'ANDROID' and product is not null 
group by 
    PRODUCT; 

EXPLAIN PLAN:

EXPLAIN PLAN 
    SET statement_id = 'ex_plan1' FOR 
select 
     PRODUCT , 
     RTRIM(XMLAGG(XMLELEMENT(E, NAME,', ').EXTRACT('//text()') ).GetClobVal(),',') AS DEVICE_LIST 
    from 
     t_operation 
    where 
     discriminator = 'ANDROID' and product is not null 
    group by 
     PRODUCT; 

結果:

Plan hash value: 795775875 

---------------------------------------------------------------------------------- 
| Id | Operation   | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |    | 11484 | 246K| 11 (19)| 00:00:01 | 
| 1 | SORT GROUP BY  |    | 11484 | 246K| 11 (19)| 00:00:01 | 
|* 2 | TABLE ACCESS FULL| T_OPERATION | 11992 | 257K|  9 (0)| 00:00:01 | 
---------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    2 - filter("PRODUCT" IS NOT NULL AND "DISCRIMINATOR"='ANDROID') 

Note 
----- 
    - Unoptimized XML construct detected (enable XMLOptimizationCheck for more information) 

とT_OPERATION:

CREATE TABLE "IOT"."T_OPERATION" 
    ( "ID" NUMBER(38,0) NOT NULL ENABLE, 
    "DISCRIMINATOR" VARCHAR2(50 BYTE) NOT NULL ENABLE, 
    "COUNTRY" NUMBER(38,0), 
    "NAME" VARCHAR2(255 BYTE) NOT NULL ENABLE, 
    "COMPUTER" NUMBER(38,0), 
    "PRODUCT" NUMBER(38,0), 
    "ADDRESS" NUMBER(38,0), 
    CONSTRAINT "PK_OPR_ID" PRIMARY KEY ("ID") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 655360 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "IOT" ENABLE, 
    CONSTRAINT "FK_OPR2ADR_INF" FOREIGN KEY ("ADDRESS") 
     REFERENCES "IOT"."T_ADDRESS_INFO" ("ID") ENABLE, 
    CONSTRAINT "FK_OPR2CTR" FOREIGN KEY ("COUNTRY") 
     REFERENCES "IOT"."T_COUNTRY" ("ID") ENABLE, 
    CONSTRAINT "FK_OPR2PRD" FOREIGN KEY ("PRODUCT") 
     REFERENCES "IOT"."T_TABLET" ("ID") ENABLE, 
    CONSTRAINT "FK_OPR2SRV" FOREIGN KEY ("COMPUTER") 
     REFERENCES "IOT"."T_COMPUTER" ("ID") ENABLE 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "IOT" ; 

    CREATE INDEX "IOT"."V_DEVICES_LIST_3" ON "IOT"."T_OPERATION" (UPPER("NAME")) 
    PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "IOT" ; 
+1

テーブルの大きさはどれくらいですか?どのくらい遅く "*遅い*"ですか? –

+0

説明プランはどのように見えますか?このテーブルで統計が更新されましたか?インデックスが利用されていますか? – Grayson

+1

実行計画の出力から述語情報を追加することもできますか? 'dbms_xplan.display'が示したすべて。あなたのテーブルにはどれくらいの行に 'ANDROID'がありますか? –

答えて

1

私はあなたができるとは思わない。テーブルからデータを取得することは可能な限り速くなります。フィルタが非常に選択的ではないように見えるので、おそらくフルテーブルスキャンが適していると思われます。インデックスを追加することはおそらく助かりません。とにかく比較的高速なデータ量で実現できます。

時間が集計に費やされています。 extract()の代わりにXMLQueryを使用しようとしましたが(これは廃止されています)、何かあれば遅くなりました。また、ユーザ定義のCLOBアグリゲータとcollect()メソッド(see this popular list of techniques)を試してみましたが、それもやや遅くなりました。もちろん、これは私のシステムと私が作成したテストデータとに基づいています。あなたの結果は変わるかもしれませんが、これらの選択肢はあなたに大きな利益をもたらすように思われません。

集計された名前のリストが4Kを超えることがある場合は、listagg()を使用することはできません。おそらく最初にXMLAggを使用しようとしている理由が考えられます。

残念ながら、XMLTypeとCLOBの操作を含むオーバーヘッドを生き延びなければならないようです。

1

discriminatorproduct列にインデックスを置く:

create index i_operation_disc_prod on t_operation(discriminator, product); 

discriminator='ANDROID'テーブルt_operationの行数の10%未満をもたらすと仮定します。

+0

このインデックスはPLANを改善し、実行が改善されると思います。 – Grayson

+1

@ MarkStewart - IOTは、それが実際にインデックス構成のテーブルであることを示すのではなく、スキーマとテーブルスペースの名前のようです。 –

+0

おっと! @AlexPooleあなたは正しいです。私は私の答えを編集します。私はIOTを見て、私の心はそれを「組織インデックス」に広げました! –

関連する問題