簡體   English   中英

查詢動作非常慢

[英]Query acting extremely slow

我在Oracle Database 11g企業版11.2.0.4.0-64位生產環境中查詢非常慢( 在3.859秒內獲取了50行 ),我不知道該怎么做才能優化它! 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 
  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" ;

discriminatorproduct列上添加索引:

create index i_operation_disc_prod on t_operation(discriminator, product);

假設discriminator='ANDROID'產生的數據少於表t_operation的行數的10%。

我認為你不能。 從表中檢索數據的過程將盡可能快-由於過濾器的選擇性似乎不高,因此全表掃描可能還是合適的,添加索引也不太可能。 有了這樣的數據量,無論如何都會變得相對快。

時間花費在聚合上。 我嘗試使用XMLQuery而不是extract() (因為已棄用),但速度較慢(如果有的話)。 我還嘗試了使用用戶定義的CLOB聚合器和collect()方法( 請參閱此流行的技術列表 ),它們的速度也較慢。 當然,這是在我的系統上以及我組成的測試數據的; 您的結果可能會有所不同,但這些替代方法似乎並不會給您帶來重大收益。

如果您的名稱總列表超過4K(每個產品最多只能包含17個名稱listagg() ,那么您就不能使用listagg() ,這可能就是為什么您首先嘗試使用XMLAgg的原因。

不幸的是,看起來您只需要忍受涉及XMLType和CLOB操作的開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM