Use Union instead of or to improve query performance

Source: Internet
Author: User

Yesterday, an iron buddy asked me for help via QQ and asked if the following SQL statement could be optimized.

SQL> set timing onsql> set autotrace onsql> select count (*) rowcount_lhy 2 from swgl_ddjbxx T 3 where T. fzgs_dm = '000000' 4 and (t. lrr_dm = 'e90e3fe4237c4af988477329c7f2059e' or exists 5 (select y. kh_id 6 from khgl_khywdlxx Y 7 where Y. kh_id = T. kh_id 8 and Y. sskhjl_dm = 'e90e3fe4237c4af988477329c7f2059e ') or 9 T. kpr_dm = 'e90e3fe4237c4af988477329c7f2059e ') 10 and T. xjbz = '000000' 11 and T. fromnbgl1 = '0'; SQL> set line 300sql>/rowcount_lhy ------------ 60 used time: 00: 00: 20.53 execution plan ------------------------------------------------------ plan hash value: 1217125969 bytes | ID | operation | Name | rows | bytes | cost (% CPU) | time | bytes | 0 | SELECT statement | 1 | 86 | 28048 (1) | 00:05:37 | 1 | sort aggregate | 1 | 86 | * 2 | filter | * 3 | table access full | swgl_ddjbxx | 5926 | 497k | 28048 (1) | 00:05:37 | * 4 | table access by index rowid | khgl_khywdlxx | 1 | 57 | 5 (0) | 00:00:01 | * 5 | index range scan | idx_khgl_khywdlxx_khid | 1 | 3 (0) | 00:00:01 | descripredicate information (identified by Operation ID ): ------------------------------------------------- 2-filter ("T ". "lrr_dm" = 'e90e3fe4237c4af988477329c7f2059e' or "T ". "kpr_dm" = 'e90e3fe4237c4af988477329c7f2059e 'or exists (select 0 from "khgl_khywdlxx" "Y" where "Y ". "kh_id" =: B1 and "Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 3-filter ("T ". "fromnbgl1" = '0' and "T ". "xjbz" = '000000' and "T ". "fzgs_dm" = '000000') 4-filter ("Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 5-access ("Y ". "kh_id" =: B1) statistics: 0 recursive cballs 0 dB block gets 804560 consistent gets 71127 physical reads 0 redo size 516 bytes sent via SQL * Net to client 469 bytes received via SQL * Net From Client 2 SQL * net roundtrips to/from client 0 sorts (memory) 0 sorts (Disk) 1 rows processed

After five seconds, I replied to my buddy and said that he had expanded or into union, but that guy's SQL was really amazing (Don't scold me), so I had to help write one.

SQL> select count (*) 2 from (select * 3 from swgl_ddjbxx T 4 where T. lrr_dm = 'e90e3fe4237c4af988477329c7f2059e '5 and T. fzgs_dm = '000000' 6 and T. xjbz = '000000' 7 and T. fromnbgl1 = '0' 8 Union 9 select * 10 from swgl_ddjbxx T 11 where T. kpr_dm = 'e90e3fe4237c4af988477329c7f2059e '12 and T. fzgs_dm = '000000' 13 and T. xjbz = '000000' 14 and T. fromnbgl1 = '0' 15 Union 16 select * 17 from swgl_ddjbxx t 18 where exists 19 (select y. kh_id 20 from khgl_khywdlxx y 21 where Y. kh_id = T. kh_id 22 and Y. sskhjl_dm = 'e90e3fe4237c4af988477329c7f2059e ') 23 and T. fzgs_dm = '000000' 24 and T. xjbz = '000000' 25 and T. fromnbgl1 = '0'); count (*) ---------- 60 used time: 00: 00: 06.89 execution plan -------------------------------------------------------- plan hash value: 3846872744 bytes | ID | operation | Name | rows | bytes | tempspc | cost (% CPU) | time | bytes | 0 | SELECT statement | 1 | 52263 (1) | 00:10:28 | 1 | sort aggregate | 1 | 2 | View | 5996 | 52263 (1) | 00:10:28 | 3 | sort unique | 5996 | 2238k | 6344k | 52263 (47) | 00:10:28 | 4 | Union-all | * 5 | table access full | swgl_ddjbxx | 59 | 19234 | 28037 (1) | 00:05:37 | * 6 | table access by index rowid | swgl_ddjbxx | 10 | 3260 | 1209 (1) | 00:00:15 | * 7 | index range scan | idx_swgl_ddjbxx_kprdm | 4748 | 34 (0) | 00:00:01 | * 8 | table access by index rowid | swgl_ddjbxx | 1 | 326 | 5 (0) | 00:00:01 | 9 | nested loops | 5927 | 2216k | 22527 (1) | 00:04:31 | 10 | sort unique | 10165 | 565k | 1916 (1) | 00:00:23 | 11 | table access by index rowid | khgl_khywdlxx | 10165 | 565k | 1916 (1) | 00:00:23 | * 12 | index range scan | idx_khgl_khywdlxx_sskhjl | 10165 | 111 (0) | 00:00:02 | * 13 | index range scan | idx_swgl_ddjbxx_khid | 2 | 2 (0) | 00:00:01 | descripredicate information (identified by Operation ID ): ------------------------------------------------- 5-filter ("T ". "lrr_dm" = 'e90e3fe4237c4af988477329c7f2059e' and "T ". "fromnbgl1" = '0' and "T ". "xjbz" = '000000' and "T ". "fzgs_dm" = '000000') 6-filter ("T ". "fromnbgl1" = '0' and "T ". "xjbz" = '000000' and "T ". "fzgs_dm" = '000000') 7-access ("T ". "kpr_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 8-filter ("T ". "fromnbgl1" = '0' and "T ". "xjbz" = '000000' and "T ". "fzgs_dm" = '000000') 12-access ("Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 13-access ("Y ". "kh_id" = "T ". "kh_id ") statistics 1 recursive cballs 0 dB block gets 128422 consistent gets 10308 physical reads 0 redo size 512 bytes sent via SQL * Net to client 469 bytes received via SQL * Net From Client 2 SQL * net roundtrips to/from client 2 sorts (memory) 0 sorts (Disk) 1 rows processed

After the SQL statement is rewritten, the execution time is reduced from 20 seconds to 6 seconds, and the logical read speed is reduced from 804560 to 128422. The performance is still greatly improved. The optimization is not complete yet, you can create a composite index for further optimization.

Create index idx on swgl_ddjbxx (fzgs_dm, xjbz, fromnbgl1 );

After the index is created, the original SQL Execution time and execution plan are as follows:

SQL> select count (*) rowcount_lhy 2 from swgl_ddjbxx T 3 where T. fzgs_dm = '000000' 4 and (t. lrr_dm = 'e90e3fe4237c4af988477329c7f2059e' or exists 5 (select y. kh_id 6 from khgl_khywdlxx Y 7 where Y. kh_id = T. kh_id 8 and Y. sskhjl_dm = 'e90e3fe4237c4af988477329c7f2059e ') or 9 T. kpr_dm = 'e90e3fe4237c4af988477329c7f2059e ') 10 and T. xjbz = '000000' 11 and T. fromnbgl1 = '0'; rowcount_lhy ------------ 60 used time: 00: 00: 02.96 execution plan -------------------------------------------------------- plan hash value: 3049366449 bytes | ID | operation | Name | rows | bytes | cost (% CPU) | time | bytes | 0 | SELECT statement | 1 | 86 | 506 (0) | 00:00:07 | 1 | sort aggregate | 1 | 86 | * 2 | filter | 3 | table access by index rowid | swgl_ddjbxx | 5926 | 497k | 506 (0) | 00:00:07 | * 4 | index range scan | idx | 2370 | 12 (0) | 00:00:01 | * 5 | table access by index rowid | khgl_khywdlxx | 1 | 57 | 5 (0) | 00:00:01 | * 6 | index range scan | idx_khgl_khywdlxx_khid | 1 | 3 (0) | 00:00:01 | descripredicate information (identified by Operation ID ): ------------------------------------------------- 2-filter ("T ". "lrr_dm" = 'e90e3fe4237c4af988477329c7f2059e' or "T ". "kpr_dm" = 'e90e3fe4237c4af988477329c7f2059e 'or exists (select 0 from "khgl_khywdlxx" "Y" where "Y ". "kh_id" =: B1 and "Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 4-access ("T ". "fzgs_dm" = '000000' and "T ". "xjbz" = '000000' and "T ". "fromnbgl1" = '0') 5-filter ("Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 6-access ("Y ". "kh_id" =: B1) statistics 1 recursive cballs 0 dB block gets 702767 consistent gets 0 physical reads 0 redo size 516 bytes sent via SQL * Net to client 469 bytes received via SQL * Net From Client 2 SQL * net roundtrips to/from client 0 sorts (memory) 0 sorts (Disk) 1 rows processed

Rewritten SQL:

SQL> select count (*) 2 from (select * 3 from swgl_ddjbxx T 4 where T. lrr_dm = 'e90e3fe4237c4af988477329c7f2059e '5 and T. fzgs_dm = '000000' 6 and T. xjbz = '000000' 7 and T. fromnbgl1 = '0' 8 Union 9 select * 10 from swgl_ddjbxx T 11 where T. kpr_dm = 'e90e3fe4237c4af988477329c7f2059e '12 and T. fzgs_dm = '000000' 13 and T. xjbz = '000000' 14 and T. fromnbgl1 = '0' 15 Union 16 select * 17 from swgl_ddjbxx t 18 where exists 19 (select y. kh_id 20 from khgl_khywdlxx y 21 where Y. kh_id = T. kh_id 22 and Y. sskhjl_dm = 'e90e3fe4237c4af988477329c7f2059e ') 23 and T. fzgs_dm = '000000' 24 and T. xjbz = '000000' 25 and T. fromnbgl1 = '0'); count (*) ---------- 60 used time: 00: 00: 00.53 execution plan -------------------------------------------------------- plan hash value: 2947849958 bytes | ID | operation | Name | rows | bytes | tempspc | cost (% CPU) | time | bytes | 0 | SELECT statement | 1 | 3469 (1) | 00:00:42 | 1 | sort aggregate | 1 | 2 | View | 5995 | 3469 (1) | 00:00:42 | 3 | sort unique | 5995 | 2238k | 4760k | 3469 (86) | 00:00:42 | 4 | Union-all | * 5 | table access by index rowid | swgl_ddjbxx | 59 | 19234 | 506 (0) | 00:00:07 | * 6 | index range scan | idx | 2370 | 12 (0) | 00:00:01 | 7 | table access by index rowid | swgl_ddjbxx | 10 | 3260 | 50 (0) | 00:00:01 | 8 | bitmap conversion to rowids | 9 | bitmap and | 10 | bitmap conversion from rowids | | * 11 | index range scan | idx | 2370 | 12 (0) | 00:00:01 | 12 | bitmap conversion from rowids | * 13 | index range scan | idx_swgl_ddjbxx_kprdm | 2370 | 34 (0) | 00:00:01 | * 14 | hash join right semi | 5926 | 2216k | 2423 (1) | 00:00:30 | 15 | table access by index rowid | khgl_khywdlxx | 10165 | 565k | 1916 (1) | 00:00:23 | * 16 | index range scan | idx_khgl_khywdlxx_sskhjl | 10165 | 111 (0) | 00:00:02 | 17 | table access by index rowid | swgl_ddjbxx | 5926 | 1886k | 506 (0) | 00:00:07 | * 18 | index range scan | idx | 2370 | 12 (0) | 00:00:01 | identified predicate information (identified by Operation ID ): ------------------------------------------------- 5-filter ("T ". "lrr_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 6-access ("T ". "fzgs_dm" = '000000' and "T ". "xjbz" = '000000' and "T ". "fromnbgl1" = '0') 11-access ("T ". "fzgs_dm" = '000000' and "T ". "xjbz" = '000000' and "T ". "fromnbgl1" = '0') filter ("T ". "fromnbgl1" = '0' and "T ". "xjbz" = '000000' and "T ". "fzgs_dm" = '000000') 13-access ("T ". "kpr_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 14-access ("Y ". "kh_id" = "T ". "kh_id") 16-access ("Y ". "sskhjl_dm" = 'e90e3fe4237c4af988477329c7f2059e ') 18-access ("T ". "fzgs_dm" = '000000' and "T ". "xjbz" = '000000' and "T ". "fromnbgl1" = '0 ') statistics 1 recursive cballs 0 dB block gets 25628 consistent gets 0 physical reads 0 redo size 512 bytes sent via SQL * Net to client 469 bytes received via SQL * Net From Client 2 SQL * net roundtrips to/from client 1 sorts (memory) 0 sorts (Disk) 1 rows processed

Since I cannot directly connect to the DB, this SQL optimization ends here.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.