自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SQL性能優(yōu)化策略之聯(lián)合索引優(yōu)化方法

運(yùn)維 數(shù)據(jù)庫運(yùn)維
LIS_REQUISITION_INFO表的訪問先通過I_PRINT_TIME索引進(jìn)行范圍掃描,符合條件的記錄回表之后再過濾,產(chǎn)生了大量的單塊讀。

[[413295]]

本文轉(zhuǎn)載自微信公眾號「數(shù)倉寶貝庫」,作者葉樺 等 。轉(zhuǎn)載本文請聯(lián)系數(shù)倉寶貝庫公眾號。

案例:一條很簡單的SQL語句明明選擇了索引掃描,但效率還是很低,SQL語句比較簡單,是對單張表進(jìn)行查詢,示例代碼如下:

  1. SQL> set autot trace 
  2.  
  3. SQL> SELECT REQUISITION_ID PARAM1, '1' PARAM2, /*電子標(biāo)簽*/ '1' PARAM3 
  4.  
  5.   2    FROM dbo.LIS_REQUISITION_INFO 
  6.  
  7.   3   WHERE PRINT_TIME >= 
  8.  
  9.   4         TO_DATE('2019-01-01 00:00:00''YYYY-MM-DD HH24:MI:SS'
  10.  
  11.   5     AND PRINT_TIME < SYSDATE 
  12.  
  13.   6     and length(requisition_id) = 12 
  14.  
  15.   7     AND (TAT1_STATE = '' OR TAT1_STATE IS NULL
  16.  
  17.   8     AND ROWNUM < 800; 
  18.  
  19.  
  20.  
  21. Execution Plan 
  22.  
  23. ---------------------------------------------------------- 
  24.  
  25. Plan hash value: 1151136383 
  26.  
  27. ------------------------------------------------------------------------------------------ 
  28.  
  29. | Id  | Operation            |Name                |Rows  | Bytes | Cost (%CPU)| Time     | 
  30.  
  31. ------------------------------------------------------------------------------------------ 
  32.  
  33. |   0 | SELECT STATEMENT     |                    |  799 | 18377 |   160K  (1)| 00:32:03 | 
  34.  
  35. |*  1 |  COUNT STOPKEY       |                    |      |       |            |          | 
  36.  
  37. |*  2 |   FILTER             |                    |      |       |            |          | 
  38.  
  39. |*  3 |    TABLE ACCESS BY  
  40.  
  41.                 INDEX ROWID  |LIS_REQUISITION_INFO|  800 | 18400 |  160K   (1)| 00:32:03 | 
  42.  
  43. |*  4 |     INDEX RANGE SCAN |I_PRINT_TIME        |      |       |  3799   (1)| 00:00:46 | 
  44.  
  45. ------------------------------------------------------------------------------------------ 
  46.  
  47. Predicate Information (identified by operation id): 
  48.  
  49. --------------------------------------------------- 
  50.  
  51.    1 - filter(ROWNUM<800) 
  52.  
  53.    2 - filter(SYSDATE@!>TO_DATE(' 2019-01-01 00:00:00''syyyy-mm-dd hh24:mi:ss')) 
  54.  
  55.    3 - filter("TAT1_STATE" IS NULL AND LENGTH("REQUISITION_ID")=12) 
  56.  
  57.    4 - access("PRINT_TIME">=TO_DATE(' 2019-01-01 00:00:00''syyyy-mm-dd hh24:mi:ss'AND 
  58.  
  59.               "PRINT_TIME"<SYSDATE@!) 
  60.  
  61. Statistics 
  62.  
  63. ---------------------------------------------------------- 
  64.  
  65.           1  recursive calls 
  66.  
  67.           0  db block gets 
  68.  
  69.     1204017  consistent gets 
  70.  
  71.      161836  physical reads 
  72.  
  73.       19984  redo size 
  74.  
  75.         761  bytes sent via SQL*Net to client 
  76.  
  77.         520  bytes received via SQL*Net from client 
  78.  
  79.           2  SQL*Net roundtrips to/from client 
  80.  
  81.           0  sorts (memory) 
  82.  
  83.           0  sorts (disk) 
  84.  
  85.           3  rows processed 

從上述代碼的執(zhí)行計(jì)劃可以看出,Id=4的dbo.LIS_REQUISITION_INFO表選擇的索引是I_PRINT_TIME,PRINT_TIME為時(shí)間字段,邏輯讀高達(dá)1204017,下面我們看下該列的選擇性,命令如下:

  1. SQL> select /*+ NO_MERGE LEADING(a b) */ 
  2.  
  3.  b.owner, 
  4.  
  5.  b.table_name, 
  6.  
  7.  a.column_name, 
  8.  
  9.  b.num_rows, 
  10.  
  11.  a.num_distinct Cardinality, 
  12.  
  13.  ROUND(A.num_distinct * 100 / B.num_rows, 1) selectivity 
  14.  
  15.   from dba_tab_col_statistics a, dba_tables b 
  16.  
  17.  where a.owner = b.owner 
  18.  
  19.    and a.table_name = b.table_name 
  20.  
  21.    and a.owner = 'DBO' 
  22.  
  23.    and a.table_name = 'LIS_REQUISITION_INFO' 
  24.  
  25.    and a.column_name = 'PRINT_TIME'
  26.  
  27.  
  28.  
  29. OWNER   TABLE_NAME             COLUMN_NAME  NUM_ROWS  CARDINALITY  SELECTIVITY 
  30.  
  31. ------- ---------------------  -----------  --------  -----------  ----------- 
  32.  
  33. DBO     LIS_REQUISITION_INFO   PRINT_TIME   6933600   2226944      32.1 

LIS_REQUISITION_INFO的數(shù)據(jù)量為6 933 600條,PRINT_TIME列的不同值為2 226 944個(gè),選擇性高達(dá)32.1%,PRINT_TIME給定了條件時(shí)間范圍,目前從執(zhí)行計(jì)劃來看,

LIS_REQUISITION_INFO表的訪問先通過I_PRINT_TIME索引進(jìn)行范圍掃描,符合條件的記錄回表之后再過濾,產(chǎn)生了大量的單塊讀。雖然PRINT_TIME的選擇性很高,且符合索引掃描的要求,但因?yàn)槠浣o定的條件范圍太大,導(dǎo)致該字段并不是一個(gè)很好的索引選擇。

除了PRINT_TIME,該SQL還有requisition_id、TAT1_STATE和ROWNUM,下面就來看下它們的選擇性,命令如下:

  1. SQL> select /*+ NO_MERGE LEADING(a b) */ 
  2.  
  3.  b.owner, 
  4.  
  5.  b.table_name, 
  6.  
  7.  a.column_name, 
  8.  
  9.  b.num_rows, 
  10.  
  11.  a.num_distinct Cardinality, 
  12.  
  13.  ROUND(A.num_distinct * 100 / B.num_rows, 1) selectivity 
  14.  
  15.   from dba_tab_col_statistics a, dba_tables b 
  16.  
  17.  where a.owner = b.owner 
  18.  
  19.    and a.table_name = b.table_name 
  20.  
  21.    and a.owner = 'DBO' 
  22.  
  23.    and a.table_name = 'LIS_REQUISITION_INFO' 
  24.  
  25.    and a.column_name in ('PRINT_TIME''REQUISITION_ID''TAT1_STATE'); 
  26.  
  27. OWNER   TABLE_NAME            COLUMN_NAME       NUM_ROWS CARDINALITY SELECTIVITY 
  28.  
  29. ------- --------------------- -------------------------- ----------- ----------- 
  30.  
  31. DBO     LIS_REQUISITION_INFO  TAT1_STATE         6933600           2           0 
  32.  
  33. DBO     LIS_REQUISITION_INFO  REQUISITION_ID     6933600     6933600         100 
  34.  
  35. DBO     LIS_REQUISITION_INFO  PRINT_TIME         6933600     2226944        32.1 
  36.  
  37.  
  38.  
  39. SQL> select count(*), 
  40.  
  41.   from dbo.LIS_REQUISITION_INFO 
  42.  
  43.  where length(requisition_id) = 12 
  44.  
  45. COUNT(*) 
  46.  
  47. ------- 
  48.  
  49. 6968919 
  50.  
  51.  
  52.  
  53. SQL> select TAT1_STATE, count(*) 
  54.  
  55.   from dbo.LIS_REQUISITION_INFO 
  56.  
  57.  group by TAT1_STATE; 
  58.  
  59. TAT1_STAT   COUNT(*) 
  60.  
  61. ----------  -------- 
  62.  
  63.             1242217 
  64.  
  65. 1           5355366 
  66.  
  67. 2            371401 

REQUISITION_ID為主鍵的選擇性很高,但幾乎所有的記錄值都符合length (requisition_id) = 12,TAT1_STATE的數(shù)據(jù)分布存在傾斜,條件中的TAT1_STATE = '' OR TAT1_STATE IS NULL屬于第一種情況,占總數(shù)據(jù)量的1/3。該字段為固定取值(TAT1_STATE = '' OR TAT1_STATE IS NULL)。如果 PRINT_TIME和TAT1_STATE組合創(chuàng)建聯(lián)合索引,那么效果又將如何呢?命令如下:

  1. SQL> create index dbo.idx_LIS_REQUISITION_INFO_com1 on dbo.LIS_REQUISITION_INFO 
  2.  
  3.     (PRINT_TIME,TAT1_STATE) online; 
  4.  
  5.  
  6.  
  7. SQL> SELECT /*+ index(LIS_REQUISITION_INFO dbo.idx_LIS_REQUISITION_INFO_com1) */ 
  8.  
  9.  REQUISITION_ID PARAM1, '1' PARAM2, /*電子標(biāo)簽*/ '1' PARAM3 
  10.  
  11.   FROM dbo.LIS_REQUISITION_INFO 
  12.  
  13.  WHERE PRINT_TIME >= 
  14.  
  15.        TO_DATE('2019-01-01 00:00:00''YYYY-MM-DD HH24:MI:SS'
  16.  
  17.    AND PRINT_TIME < SYSDATE 
  18.  
  19.    and length(requisition_id) = 12 
  20.  
  21.    AND (TAT1_STATE = '' OR TAT1_STATE IS NULL
  22.  
  23.    AND ROWNUM < 800; 
  24.  
  25. Execution Plan 
  26.  
  27. ---------------------------------------------------------- 
  28.  
  29. Plan hash value: 1406522876 
  30.  
  31. ----------------------------------------------------------------------------------------------------- 
  32.  
  33. | Id  | Operation            | Name                        |Starts|E-Rows|A-Rows|   A-Time  |Buffers| 
  34.  
  35. ----------------------------------------------------------------------------------------------------- 
  36.  
  37. |   0 | SELECT STATEMENT     |                             |    1 |      |    6 |00:00:00.27|  8146 | 
  38.  
  39. |*  1 |  COUNT STOPKEY       |                             |    1 |      |    6 |00:00:00.27|  8146 | 
  40.  
  41. |*  2 |   FILTER             |                             |    1 |      |    6 |00:00:00.27|  8146 | 
  42.  
  43. |*  3 |    TABLE ACCESS BY  
  44.  
  45.                INDEX ROWID   |LIS_REQUISITION_INFO         |    1 |  144 |    6 |00:00:00.27|  8146 | 
  46.  
  47. |*  4 |     INDEX RANGE SCAN |IDX_LIS_REQUISITION_INFO_COM1|    1 |14398 |    8 |00:00:00.27|  8140 | 
  48.  
  49. ----------------------------------------------------------------------------------------------------- 
  50.  
  51. Predicate Information (identified by operation id): 
  52.  
  53. --------------------------------------------------- 
  54.  
  55.    1 - filter(ROWNUM<800) 
  56.  
  57.    2 - filter(SYSDATE@!>TO_DATE(' 2019-01-01 00:00:00''syyyy-mm-dd hh24:mi:ss')) 
  58.  
  59.    3 - filter(LENGTH("REQUISITION_ID")=12) 
  60.  
  61.    4 - access("PRINT_TIME">=TO_DATE(' 2019-01-01 00:00:00''syyyy-mm-dd hh24:mi:ss'AND "TAT1_STATE" 
  62.  
  63.               IS NULL AND "PRINT_TIME"<SYSDATE@!) 
  64.  
  65.        filter("TAT1_STATE" IS NULL
  66.  
  67. Statistics 
  68.  
  69. ---------------------------------------------------------- 
  70.  
  71.           1  recursive calls 
  72.  
  73.           0  db block gets 
  74.  
  75.        8008  consistent gets 
  76.  
  77.        8014  physical reads 
  78.  
  79.           0  redo size 
  80.  
  81.         471  bytes sent via SQL*Net to client 
  82.  
  83.         508  bytes received via SQL*Net from client 
  84.  
  85.           1  SQL*Net roundtrips to/from client 
  86.  
  87.           0  sorts (memory) 
  88.  
  89.           0  sorts (disk) 
  90.  
  91.           0  rows processed 

創(chuàng)建索引之后,SQL性能有了明顯的提升,邏輯讀從原來的1204017降到8008,執(zhí)行時(shí)間也從原來的32分鐘降至27秒。

上述案例介紹了簡單的復(fù)合索引優(yōu)化,很多情況下,雖然改寫SQL能夠更好地解決問題,但我們往往很難讓開發(fā)商去做出修改,因此索引優(yōu)化變得尤為重要。當(dāng)表上存在多個(gè)過濾條件時(shí),字段在表中的選擇性只能作為參考而不能成為最終依據(jù),在實(shí)際工作中,我們應(yīng)該根據(jù)業(yè)務(wù)特點(diǎn)對多個(gè)字段進(jìn)行組合分析。在很多情況下,單個(gè)字段的選擇性比較低,多個(gè)字段的選擇性會成倍增長。

 

責(zé)任編輯:武曉燕 來源: 數(shù)倉寶貝庫
相關(guān)推薦

2021-07-16 23:01:03

SQL索引性能

2018-01-09 16:56:32

數(shù)據(jù)庫OracleSQL優(yōu)化

2017-08-25 15:28:20

Oracle性能優(yōu)化虛擬索引

2023-05-10 10:30:02

性能優(yōu)化Tomcat

2009-09-08 09:45:23

App Engine性

2020-10-19 19:45:58

MySQL數(shù)據(jù)庫優(yōu)化

2018-03-30 14:30:10

數(shù)據(jù)庫SQL語句性能優(yōu)化

2018-04-19 09:02:14

SQL ServerSQL性能優(yōu)化

2018-03-30 13:59:22

數(shù)據(jù)庫SQL語句性能優(yōu)化

2016-12-14 19:04:16

Spark SQL優(yōu)化

2018-06-07 08:54:01

MySQL性能優(yōu)化索引

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動互聯(lián)網(wǎng)數(shù)據(jù)存儲

2011-07-11 15:28:19

MySQL索引優(yōu)化

2016-12-08 15:47:54

sql優(yōu)化數(shù)據(jù)

2024-10-09 23:32:50

2017-09-05 12:44:15

MySQLSQL優(yōu)化覆蓋索引

2022-02-16 14:10:51

服務(wù)器性能優(yōu)化Linux

2009-06-30 11:23:02

性能優(yōu)化

2021-11-29 11:13:45

服務(wù)器網(wǎng)絡(luò)性能

2019-12-13 10:25:08

Android性能優(yōu)化啟動優(yōu)化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號