精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

國產集中式數據庫SQL評測 — 邏輯優化

原創
數據庫 其他數據庫
謂詞重寫,又稱為等價謂詞重寫,是指將原執行效率低的謂詞改寫為效率高的謂詞并重寫SQL,從而提高SQL的整體執行效率的一種優化手段。其本質是在于不同謂詞的處理效率存在差異所導致。

數據庫的邏輯優化,是查詢優化過程中的關鍵階段,旨在通過調整查詢語句的邏輯結構和操作順序,生成更高效的執行計劃,而不涉及底層存儲結構或硬件資源。其核心在于利用關系代數的等價變換和查詢重寫技術,減少計算量和中間結果規模。

1. 邏輯優化—謂詞重寫

謂詞重寫,又稱為等價謂詞重寫,是指將原執行效率低的謂詞改寫為效率高的謂詞并重寫SQL,從而提高SQL的整體執行效率的一種優化手段。其本質是在于不同謂詞的處理效率存在差異所導致。常見的謂詞重寫規則如下

1).優化規則

1.png1.png

2).數據庫支持情況

2.png2.png

3).數據庫測評

-- Oracle-- Like(未改寫)SQL> select * from emp where emp_name like 'emp12%';--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   118 |  3304 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   118 |  3304 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("EMP_NAME" LIKE 'emp12%')
-- Between And(改寫)SQL> select * from emp where salary between 1000 and 1200;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |  1799 | 50372 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |  1799 | 50372 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("SALARY"<=1200 AND "SALARY">=1000)   -- IN-OR/IN-ANY(改寫)SQL> select * from emp where dept_id in (20,30);--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   189 |  5292 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   189 |  5292 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=20 OR "DEPT_ID"=30)   -- OR-ANY(未改寫)SQL> select * from emp where dept_id=20 or dept_id=30;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   189 |  5292 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   189 |  5292 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=20 OR "DEPT_ID"=30)   --ALL/ANY-MIN/MAX(改寫)SQL> SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);----------------------------------------------------------------------------| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |----------------------------------------------------------------------------|   0 | SELECT STATEMENT    |      |  8999 |   325K|    32   (7)| 00:00:01 ||   1 |  MERGE JOIN SEMI    |      |  8999 |   325K|    32   (7)| 00:00:01 ||   2 |   SORT JOIN         |      | 10000 |   273K|    16   (7)| 00:00:01 ||   3 |    TABLE ACCESS FULL| EMP  | 10000 |   273K|    15   (0)| 00:00:01 ||*  4 |   SORT UNIQUE       |      |   101 |   909 |    16   (7)| 00:00:01 ||*  5 |    TABLE ACCESS FULL| EMP  |   101 |   909 |    15   (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - access(INTERNAL_FUNCTION("SALARY")>INTERNAL_FUNCTION("SALARY"))       filter(INTERNAL_FUNCTION("SALARY")>INTERNAL_FUNCTION("SALARY"))   5 - filter("DEPT_ID"=20)-- NOT(改寫)SQL> select * from emp where not dept_id!=20;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   101 |  2828 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   101 |  2828 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=20)-- OR-UNION(未改寫)SQL> select * from emp where dept_id=1 or dept_id=2;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   141 |  3948 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   141 |  3948 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=1 OR "DEPT_ID"=2)   -- DM-- Like(改寫)SQL> explain select * from emp where emp_name like 'emp12%';1   #NSET2: [1, 111, 163]2     #PRJT2: [1, 111, 163]; exp_num(6), is_atom(FALSE)3       #BLKUP2: [1, 111, 163]; IDX_EMP_NAME(EMP)4         #SSEK2: [1, 111, 163]; scan_type(ASC), IDX_EMP_NAME(EMP), scan_range['emp12','emp13'), is_global(0)
-- Between And(改寫)SQL> explain select * from emp where salary between 1000 and 1200;1   #NSET2: [1, 1762, 163]2     #PRJT2: [1, 1762, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 1762, 163]; (EMP.SALARY >= var1 AND EMP.SALARY <= var2) SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- IN-OR/IN-ANY(不改寫)SQL> explain select * from emp where dept_id in (20,30);1   #NSET2: [3, 500, 193]2     #PRJT2: [3, 500, 193]; exp_num(6), is_atom(FALSE)3       #HASH2 INNER JOIN: [3, 500, 193];  KEY_NUM(1); KEY(DMTEMPVIEW_889193477.colname=EMP.DEPT_ID) KEY_NULL_EQU(0)4         #CONST VALUE LIST: [1, 2, 30]; row_num(2), col_num(1)5         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)   -- OR-ANY(未改寫)SQL> explain select * from emp where dept_id=20 or dept_id=30;1   #NSET2: [3, 500, 193]2     #PRJT2: [3, 500, 193]; exp_num(6), is_atom(FALSE)3       #HASH2 INNER JOIN: [3, 500, 193];  KEY_NUM(1); KEY(DMTEMPVIEW_889193481.colname=EMP.DEPT_ID) KEY_NULL_EQU(0)4         #CONST VALUE LIST: [1, 2, 30]; row_num(2), col_num(1)5         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)   --ALL/ANY-MIN/MAX(未改寫)SQL> explain SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);1   #NSET2: [5, 500, 60]2     #PRJT2: [5, 500, 60]; exp_num(6), is_atom(FALSE)3       #HASH RIGHT SEMI JOIN32: [5, 500, 60]; op any;, key_num(0) join condition(EMP.SALARY > DMTEMPVIEW_889193482.colname)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)5         #PRJT2: [1, 250, 60]; exp_num(1), is_atom(FALSE)6           #SLCT2: [1, 250, 60]; EMP.DEPT_ID = var17             #CSCN2: [1, 10000, 60]; INDEX33555484(EMP); btr_scan(1)
-- NOT(改寫)SQL> explain select * from emp where not dept_id!=20;1   #NSET2: [1, 250, 163]2     #PRJT2: [1, 250, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 250, 163]; EMP.DEPT_ID = var1 SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)
-- OR-UNION(未改寫)SQL> explain select * from emp where dept_id=1 or dept_id=2;1   #NSET2: [3, 500, 193]2     #PRJT2: [3, 500, 193]; exp_num(6), is_atom(FALSE)3       #HASH2 INNER JOIN: [3, 500, 193];  KEY_NUM(1); KEY(DMTEMPVIEW_889193490.colname=EMP.DEPT_ID) KEY_NULL_EQU(0)4         #CONST VALUE LIST: [1, 2, 30]; row_num(2), col_num(1)5         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)   -- MySQL
-- Like(未改寫)mysql> explain select * from emp where emp_name like 'emp12%';+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+| id | select_type | table | partitions | type  | possible_keys | key          | key_len | ref  | rows | filtered | Extra                 |+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+|  1 | SIMPLE      | emp   | NULL       | range | idx_emp_name  | idx_emp_name | 33      | NULL |  111 |   100.00 | Using index condition |+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`emp_name` like 'emp12%') |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- Between And(未改寫)mysql> explain select * from emp where salary between 1000 and 1200;+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+| id | select_type | table | partitions | type  | possible_keys  | key            | key_len | ref  | rows | filtered | Extra                 |+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+|  1 | SIMPLE      | emp   | NULL       | range | idx_emp_salary | idx_emp_salary | 5       | NULL | 1328 |   100.00 | Using index condition |+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message                                                                                                                                                                                                                                                                                       |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`salary` between 1000 and 1200) |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- IN-OR/IN-ANY(未改寫)mysql> explain select * from emp where dept_id in (20,30);+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    20.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message                                                                                                                                       |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` in (20,30)) |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- OR-ANY(未改寫)mysql> explain select * from emp where dept_id=20 or dept_id=30;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    19.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where ((`testdb`.`emp`.`dept_id` = 20) or (`testdb`.`emp`.`dept_id` = 30)) |+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
--ALL/ANY-MIN/MAX(改寫)mysql> explain SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | PRIMARY     | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    66.67 | Using where ||  2 | SUBQUERY    | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+2 rows in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where <nop>((`testdb`.`emp`.`salary` > (/* select#2 */ select min(`testdb`.`emp`.`salary`) from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = 20)))) |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- NOT(改寫)mysql> explain select * from emp where not dept_id!=20;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message                                                                                                                                 |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = 20) |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- OR-UNION(未改寫)mysql> explain select * from emp where dept_id=1 or dept_id=2;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    19.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where ((`testdb`.`emp`.`dept_id` = 1) or (`testdb`.`emp`.`dept_id` = 2)) |+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- Kingbase
-- Like(未改寫)TEST=# explain select * from emp where emp_name like 'emp12%';                               QUERY PLAN------------------------------------------------------------------------ Gather  (cost=1000.00..16394.33 rows=100 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=42 width=42)         Filter: ((emp_name)::text ~~ 'emp12%'::text)         -- Between And (改寫)TEST=# explain select * from emp where salary between 1000 and 1200;                                             QUERY PLAN----------------------------------------------------------------------------------------------------- Bitmap Heap Scan on emp  (cost=4857.22..17791.45 rows=183882 width=42)   Recheck Cond: ((salary >= '1000'::double precision) AND (salary <= '1200'::double precision))   ->  Bitmap Index Scan on idx_emp_salary  (cost=0.00..4811.24 rows=183882 width=0)         Index Cond: ((salary >= '1000'::double precision) AND (salary <= '1200'::double precision))         -- IN-OR/IN-ANY(改寫為ANY)TEST=# explain select * from emp where dept_id in (20,30);                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..18284.33 rows=19000 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=7917 width=42)         Filter: (dept_id = ANY ('{20,30}'::numeric[]))
-- OR-ANY(未改寫)TEST=# explain select * from emp where dept_id=20 or dept_id=30;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..19317.00 rows=18910 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..16426.00 rows=7879 width=42)         Filter: ((dept_id = '20'::numeric) OR (dept_id = '30'::numeric))          -- ALL/ANY-MIN/MAX(未改寫)TEST=# explain SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);                                            QUERY PLAN-------------------------------------------------------------------------------------------------- Gather  (cost=1000.42..1009054.30 rows=333333 width=42)   Workers Planned: 2   ->  Nested Loop Semi Join  (cost=0.42..974721.00 rows=138889 width=42)         ->  Parallel Seq Scan on emp  (cost=0.00..14342.67 rows=416667 width=42)         ->  Index Scan using idx_emp_salary on emp emp_1  (cost=0.42..6667.14 rows=3156 width=8)               Index Cond: (salary < emp.salary)               Filter: (dept_id = '20'::numeric)               -- NOT(改寫)               TEST=# explain select * from emp where not dept_id!=20;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..17331.03 rows=9467 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=3945 width=42)         Filter: (dept_id = '20'::numeric)         -- OR-UNION(未改寫)TEST=# explain select * from emp where dept_id=1 or dept_id=2;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..18889.70 rows=14637 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..16426.00 rows=6099 width=42)         Filter: ((dept_id = '1'::numeric) OR (dept_id = '2'::numeric))             -- YashanDB-- Like(未改寫)SQL> explain select * from emp where emp_name like 'emp12%';+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||  1 |  TABLE ACCESS BY INDEX ROWID   | EMP                  | TESTUSER   |       118|        1( 0)|                                ||* 2 |   INDEX RANGE SCAN             | IDX_EMP_NAME         | TESTUSER   |        60|        1( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   2 - Predicate : access("EMP"."EMP_NAME" LIKE 'emp12%')                   filter("EMP"."EMP_NAME" LIKE 'emp12%')
-- Between And(改寫)SQL> explain select * from emp where salary between 1000 and 1200;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||  1 |  TABLE ACCESS BY INDEX ROWID   | EMP                  | TESTUSER   |       880|        6( 0)|                                ||* 2 |   INDEX RANGE SCAN             | IDX_EMP_SALARY       | TESTUSER   |       880|        2( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   2 - Predicate : access("EMP"."SALARY" >= 1000 AND "EMP"."SALARY"  <= 1200)   -- IN-OR/IN-ANY(不改寫)SQL> explain select * from emp where dept_id in (20,30);+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |       200|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" IN [20, 30])   -- OR-ANY(未改寫)SQL> explain select * from emp where dept_id=20 or dept_id=30;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |       152|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 20 OR "EMP"."DEPT_ID" = 30)   --ALL/ANY-MIN/MAX(改寫)SQL> explain SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||  1 |  SUBQUERY                      | QUERY[1]             |            |          |             |                                ||  2 |   AGGREGATE                    |                      |            |         1|        1( 0)|                                ||  3 |    FIRST ROW                   |                      |            |         1|        1( 0)|                                ||* 4 |     TABLE ACCESS BY INDEX ROWID| EMP                  | TESTUSER   |         1|        1( 0)|                                ||  5 |      INDEX FULL SCAN (MIN/MAX) | IDX_EMP_SALARY       | TESTUSER   |         1|        1( 0)|                                ||* 6 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |      3301|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Subquery NDV info - NDV percentage: 0.000000, NDV Expression: ()   4 - Predicate : filter("EMP"."DEPT_ID" = 20)   6 - Predicate : filter("EMP"."SALARY" > QUERY[1])   -- NOT(改寫)SQL> explain select * from emp where not dept_id!=20;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |       103|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 20)   -- OR-UNION(不改寫)SQL> explain select * from emp where dept_id=1 or dept_id=2;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |       151|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 1 OR "EMP"."DEPT_ID" = 2)
-- Vastbase
-- Like(未改寫)vastbase=> explain select * from emp where emp_name like 'emp12%';                      QUERY PLAN------------------------------------------------------ Seq Scan on emp  (cost=0.00..243.00 rows=1 width=44)   Filter: ((emp_name)::text ~~ 'emp12%'::text)         -- Between And (改寫)vastbase=> explain select * from emp where salary between 1000 and 1200;                                           QUERY PLAN------------------------------------------------------------------------------------------------- Bitmap Heap Scan on emp  (cost=50.84..196.05 rows=1814 width=44)   Recheck Cond: ((salary >= 1000::double precision) AND (salary <= 1200::double precision))   ->  Bitmap Index Scan on idx_emp_salary  (cost=0.00..50.39 rows=1814 width=0)         Index Cond: ((salary >= 1000::double precision) AND (salary <= 1200::double precision))                  -- IN-OR/IN-ANY(改寫為ANY)vastbase=> explain select * from emp where dept_id in (20,30);                       QUERY PLAN-------------------------------------------------------- Seq Scan on emp  (cost=0.00..243.00 rows=204 width=44)   Filter: (dept_id = ANY ('{20,30}'::number[]))
-- OR-ANY(未改寫)vastbase=> explain select * from emp where dept_id=20 or dept_id=30;                          QUERY PLAN-------------------------------------------------------------- Seq Scan on emp  (cost=0.00..268.00 rows=203 width=44)   Filter: ((dept_id = 20::number) OR (dept_id = 30::number))          -- ALL/ANY-MIN/MAX(未改寫)vastbase=> explain SELECT * FROM emp WHERE salary > ANY (  SELECT salary FROM emp WHERE dept_id=20);                            QUERY PLAN------------------------------------------------------------------ Nested Loop Semi Join  (cost=0.00..9677.06 rows=3333 width=44)   Join Filter: (testuser.emp.salary > testuser.emp.salary)   ->  Seq Scan on emp  (cost=0.00..218.00 rows=10000 width=44)   ->  Materialize  (cost=0.00..243.46 rows=91 width=8)         ->  Seq Scan on emp  (cost=0.00..243.00 rows=91 width=8)               Filter: (dept_id = 20::number)               -- NOT(改寫)               vastbase=> explain select * from emp where not dept_id!=20;                      QUERY PLAN------------------------------------------------------- Seq Scan on emp  (cost=0.00..243.00 rows=91 width=44)   Filter: (dept_id = 20::number)         -- OR-UNION(未改寫)vastbase=> explain select * from emp where dept_id=1 or dept_id=2;                         QUERY PLAN------------------------------------------------------------ Seq Scan on emp  (cost=0.00..268.00 rows=196 width=44)   Filter: ((dept_id = 1::number) OR (dept_id = 2::number))

2. 邏輯優化—條件化簡

條件化簡,是指將語句中的條件子句部分優化,選擇執行代價更小或更容易利用到索引、約束等的情況。從形式上看,條件子句可能由一元操作符、二元操作符、多元操作符組成。對于一元操作符而言,如果是相等運算,則比其他運算更易利用索引,且元組更少(選擇率低的可能性更大);如果是范圍運算,則應盡可能利用索引;如果能利用約束,則可以簡化一些表達式,如非空約束有助于在條件表達式中判斷對應列所在的表達式的值;如果表達式可以求值,則先求值有利于整個條件子句的計算。條件子句優化的本質是:盡早推知運算的結果以有利于對元組數進行計算,使得根據代價估算模型(元組數是重要的計算依據)可以準確地推演出最優查詢執行計劃。

1).優化規則

3.png3.png

2).數據庫支持情況

4.png4.png

3).數據庫測評

-- Oracle-- Having 并入 Where(不支持)SQL> SELECT * FROM emp where dept_id=100 HAVING salary > 5000;SELECT * FROM emp where dept_id=100 HAVING salary > 5000                                           *ERROR at line 1:ORA-00979: not a GROUP BY expression--去除冗余括號SQL> SELECT * FROM emp WHERE ((dept_id=2));--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   102 |  2856 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   102 |  2856 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=2)   -- 常量傳遞(支持)SQL> select * from emp where dept_id=10 and emp_id=dept_id;--------------------------------------------------------------------------------------| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |        |     1 |    28 |     2   (0)| 00:00:01 ||*  1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    28 |     2   (0)| 00:00:01 ||*  2 |   INDEX UNIQUE SCAN         | EMP_PK |     1 |       |     1   (0)| 00:00:01 |--------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=10)   2 - access("EMP_ID"=10)   -- 消除死碼(支持)SQL> select * from emp where (0>1) or dept_id=10;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |    98 |  2744 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |    98 |  2744 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=10)   -- 表達式計算(支持)SQL> select * from emp where dept_id=1+2;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   107 |  2996 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   107 |  2996 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"=3)   -- 等式變換(不支持)SQL> select * from emp where -dept_id=-10;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   100 |  2800 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |   100 |  2800 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter((-"DEPT_ID")=(-10))   -- 不等式轉換(支持)SQL> select * from emp where salary >1100 and salary>2000;----------------------------------------------------------------------------------------------| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |----------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |                |     1 |    28 |     4   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY INDEX ROWID| EMP            |     1 |    28 |     4   (0)| 00:00:01 ||*  2 |   INDEX RANGE SCAN          | IDX_EMP_SALARY |     1 |       |     2   (0)| 00:00:01 |----------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   2 - access("SALARY">2000)   --謂詞傳遞閉包(支持)SQL> select * from emp where emp_id>dept_id and dept_id>900;----------------------------------------------------------------------------------------------| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |----------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |                |     1 |    28 |     3   (0)| 00:00:01 ||*  1 |  TABLE ACCESS BY INDEX ROWID| EMP            |     1 |    28 |     3   (0)| 00:00:01 ||*  2 |   INDEX RANGE SCAN          | IDX_EMP_DEPTID |     1 |       |     2   (0)| 00:00:01 |----------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("EMP_ID">900 AND "EMP_ID">"DEPT_ID")   2 - access("DEPT_ID">900)   -- 等價合取范式(支持)SQL> select * from emp where (0>1) and dept_id=10;---------------------------------------------------------------------------| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |---------------------------------------------------------------------------|   0 | SELECT STATEMENT   |      |     1 |    28 |     0   (0)|          ||*  1 |  FILTER            |      |       |       |            |          ||*  2 |   TABLE ACCESS FULL| EMP  |    98 |  2744 |    15   (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter(NULL IS NOT NULL)   2 - filter("DEPT_ID"=10)   -- AND 操作符交換(不支持)SQL> select * from emp where dept_id+emp_id=1000 and salary>900;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |    90 |  2520 |    15   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| EMP  |    90 |  2520 |    15   (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("DEPT_ID"+"EMP_ID"=1000 AND "SALARY">900)   -- DM-- Having 并入 Where(不支持)SQL> explain  SELECT * FROM emp where dept_id=100 HAVING salary > 5000;explain  SELECT * FROM emp where dept_id=100 HAVING salary > 5000;[-4028]:Error in line: 1Invalid having item.
--去除冗余括號(支持)SQL> explain SELECT * FROM emp WHERE ((dept_id=2));1   #NSET2: [1, 250, 163]2     #PRJT2: [1, 250, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 250, 163]; EMP.DEPT_ID = var1 SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- 常量傳遞(不支持)SQL> explain select * from emp where dept_id=10 and emp_id=dept_id;1   #NSET2: [1, 1, 163]2     #PRJT2: [1, 1, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 1, 163]; EMP.DEPT_ID = var14         #BLKUP2: [1, 1, 163]; INDEX33555485(EMP)5           #SSEK2: [1, 1, 163]; scan_type(ASC), INDEX33555485(EMP), scan_range[exp_cast(10),exp_cast(10)], is_global(0)   -- 消除死碼(支持)SQL> explain select * from emp where (0>1) or dept_id=10;1   #NSET2: [1, 250, 163]2     #PRJT2: [1, 250, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 250, 163]; EMP.DEPT_ID = var1 SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- 表達式計算(支持)SQL> explain select * from emp where dept_id=1+2;1   #NSET2: [1, 250, 163]2     #PRJT2: [1, 250, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 250, 163]; EMP.DEPT_ID = var2 SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- 等式變換(不支持)SQL> explain select * from emp where -dept_id=-10;1   #NSET2: [1, 250, 163]2     #PRJT2: [1, 250, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 250, 163]; -EMP.DEPT_ID = var2 SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- 不等式轉換(支持)SQL> explain select * from emp where salary >1100 and salary>2000;1   #NSET2: [1, 1, 163]2     #PRJT2: [1, 1, 163]; exp_num(6), is_atom(FALSE)3       #BLKUP2: [1, 1, 163]; IDX_EMP_SALARY(EMP)4         #SSEK2: [1, 1, 163]; scan_type(ASC), IDX_EMP_SALARY(EMP), scan_range(exp_cast(2000),max], is_global(0)
--謂詞傳遞閉包(不支持)SQL> explain select * from emp where emp_id>dept_id and dept_id>900;1   #NSET2: [1, 25, 163]2     #PRJT2: [1, 25, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 25, 163]; (EMP.DEPT_ID > var1 AND EMP.EMP_ID > EMP.DEPT_ID) SLCT_PUSHDOWN(TRUE)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP) NEED_SLCT(TRUE); btr_scan(1)   -- 等價合取范式(支持)SQL> explain select * from emp where (0>1) and dept_id=10;1   #NSET2: [1, 1, 163]2     #PRJT2: [1, 1, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 1, 163];  FALSE4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)   -- AND 操作符交換(支持)SQL> explain select * from emp where dept_id+emp_id=1000 and salary>900;1   #NSET2: [1, 225, 163]2     #PRJT2: [1, 225, 163]; exp_num(6), is_atom(FALSE)3       #SLCT2: [1, 225, 163]; (EMP.SALARY > var1 AND EMP.DEPT_ID+EMP.EMP_ID = var2)4         #CSCN2: [1, 10000, 163]; INDEX33555484(EMP); btr_scan(1)
-- MySQL
-- Having 并入 Where(未改寫)mysql> explain SELECT * FROM emp where dept_id=100 HAVING salary > 5000;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = 100) having (`testdb`.`emp`.`salary` > 5000) |+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
--去除冗余括號mysql> explain SELECT * FROM emp WHERE ((dept_id=2));+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message                                                                                                                                        |+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = 2) |+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 常量傳遞(支持)mysql> explain select * from emp where dept_id=10 and emp_id=dept_id;+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra         |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | Impossible WHERE noticed after reading const tables |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+
-- 消除死碼(支持)mysql> explain select * from emp where (0>1) or dept_id=10;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = 10) |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 表達式計算(支持)mysql> explain select * from emp where dept_id=1+2;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    10.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (`testdb`.`emp`.`dept_id` = <cache>((1 + 2))) |+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 等式變換(不支持)mysql> explain select * from emp where -dept_id=-10;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |   100.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.01 sec)
mysql> show warnings;+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (-(`testdb`.`emp`.`dept_id`) = <cache>(-(10))) |+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 不等式轉換(不支持)mysql> explain select * from emp where salary >1100 and salary>2000;+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+| id | select_type | table | partitions | type  | possible_keys  | key            | key_len | ref  | rows | filtered | Extra                 |+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+|  1 | SIMPLE      | emp   | NULL       | range | idx_emp_salary | idx_emp_salary | 5       | NULL |  421 |   100.00 | Using index condition |+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.01 sec)
mysql> show warnings;+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where ((`testdb`.`emp`.`salary` > 1100) and (`testdb`.`emp`.`salary` > 2000)) |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
--謂詞傳遞閉包(不支持)mysql> explain select * from emp where emp_id>dept_id and dept_id>900;+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10117 |    11.11 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.01 sec)
mysql> show warnings;+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where ((`testdb`.`emp`.`emp_id` > `testdb`.`emp`.`dept_id`) and (`testdb`.`emp`.`dept_id` > 900)) |+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 等價合取范式(支持)mysql> explain select * from emp where (0>1) and dept_id=10;+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra            |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | Impossible WHERE |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+1 row in set, 1 warning (0.00 sec)
mysql> show warnings;+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where false |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- AND 操作符交換(支持)mysql> explain select * from emp where dept_id+emp_id=1000 and salary>900;+----+-------------+-------+------------+------+----------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys  | key  | key_len | ref  | rows  | filtered | Extra       |+----+-------------+-------+------------+------+----------------+------+---------+------+-------+----------+-------------+|  1 | SIMPLE      | emp   | NULL       | ALL  | idx_emp_salary | NULL | NULL    | NULL | 10117 |    88.96 | Using where |+----+-------------+-------+------------+------+----------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.01 sec)
mysql> show warnings;+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message                                                       |+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note  | 1003 | /* select#1 */ select `testdb`.`emp`.`emp_id` AS `emp_id`,`testdb`.`emp`.`dept_id` AS `dept_id`,`testdb`.`emp`.`emp_name` AS `emp_name`,`testdb`.`emp`.`birthday` AS `birthday`,`testdb`.`emp`.`salary` AS `salary` from `testdb`.`emp` where (((`testdb`.`emp`.`dept_id` + `testdb`.`emp`.`emp_id`) = 1000) and (`testdb`.`emp`.`salary` > 900)) |+-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- KingBase-- Having 并入 Where(不支持)TEST=# explain SELECT * FROM emp where dept_id=100 HAVING salary > 5000;ERROR:  column "emp.emp_id" must appear in the GROUP BY clause or be used in an aggregate function
--去除冗余括號TEST=# explain SELECT * FROM emp WHERE ((dept_id=2));                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..17401.03 rows=10167 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=4236 width=42)         Filter: (dept_id = '2'::numeric)
-- 常量傳遞(支持)TEST=# explain select * from emp where dept_id=10 and emp_id=dept_id;                            QUERY PLAN------------------------------------------------------------------- Index Scan using EMP_PK on emp  (cost=0.42..8.45 rows=1 width=42)   Index Cond: (emp_id = '10'::numeric)   Filter: (dept_id = '10'::numeric)   -- 消除死碼(支持)TEST=# explain select * from emp where (0>1) or dept_id=10;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..17377.63 rows=9933 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=4139 width=42)         Filter: (dept_id = '10'::numeric)
-- 表達式計算(支持)TEST=# explain select * from emp where dept_id=1+2;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..17447.63 rows=10633 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..15384.33 rows=4430 width=42)         Filter: (dept_id = '3'::numeric)
-- 等式變換(不支持)TEST=# explain select * from emp where -dept_id=-10;                                QUERY PLAN-------------------------------------------------------------------------- Gather  (cost=1000.00..17926.00 rows=5000 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..16426.00 rows=2083 width=42)         Filter: ((- dept_id) = '-10'::numeric)
-- 不等式轉換(支持)TEST=#  explain select * from emp where salary >1100 and salary>2000;                                QUERY PLAN--------------------------------------------------------------------------- Index Scan using idx_emp_salary on emp  (cost=0.42..8.44 rows=1 width=42)   Index Cond: (salary > '2000'::double precision)
-- 謂詞傳遞閉包(不支持)TEST=# explain select * from emp where emp_id>dept_id and dept_id>900;                               QUERY PLAN------------------------------------------------------------------------ Gather  (cost=1000.00..17429.00 rows=30 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..16426.00 rows=12 width=42)         Filter: ((emp_id > dept_id) AND (dept_id > '900'::numeric))
-- 等價合取范式(支持)TEST=# explain select * from emp where (0>1) and dept_id=10;                QUERY PLAN------------------------------------------ Result  (cost=0.00..0.00 rows=0 width=0)   One-Time Filter: false
-- AND 操作符交換(支持)TEST=# explain select * from emp where dept_id+emp_id=1000 and salary>900;                                           QUERY PLAN------------------------------------------------------------------------------------------------- Gather  (cost=1000.00..18919.77 rows=4521 width=42)   Workers Planned: 2   ->  Parallel Seq Scan on emp  (cost=0.00..17467.67 rows=1884 width=42)         Filter: ((salary > '900'::double precision) AND ((dept_id + emp_id) = '1000'::numeric))         -- YashanDB-- Having 并入 Where(不支持)SQL> explain SELECT * FROM emp where dept_id=100 HAVING salary > 5000[1:52]YAS-04316 not a single-group group function
--去除冗余括號(支持)SQL> explain SELECT * FROM emp WHERE ((dept_id=2));+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |        89|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 2)   -- 常量傳遞(不支持)SQL> explain select * from emp where dept_id=10 and emp_id=dept_id;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |         1|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."EMP_ID" = "EMP"."DEPT_ID" AND 10 = "EMP"."DEPT_ID")   -- 消除死碼(支持)SQL> explain select * from emp where (0>1) or dept_id=10;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |        99|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 10)   -- 表達式計算(支持)SQL> explain select * from emp where dept_id=1+2;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |       114|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 3)   -- 等式變換(支持)SQL> explain select * from emp where -dept_id=-10;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |        99|       46( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" = 10)   -- 不等式轉換(支持)SQL> explain select * from emp where salary >1100 and salary>2000;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||  1 |  TABLE ACCESS BY INDEX ROWID   | EMP                  | TESTUSER   |         1|        1( 0)|                                ||* 2 |   INDEX RANGE SCAN             | IDX_EMP_SALARY       | TESTUSER   |         1|        1( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   2 - Predicate : access("EMP"."SALARY" > 2000)     --謂詞傳遞閉包(支持)SQL> explain select * from emp where emp_id>dept_id and dept_id>900;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |         1|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID" > 900 AND "EMP"."EMP_ID" > 900 AND "EMP"."EMP_ID" > "EMP"."DEPT_ID")   -- 等價合取范式(支持)SQL> explain select * from emp where (0>1) and dept_id=10;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  RESULT                        |                      |            |          |        1( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter(FALSE)   -- AND 操作符交換(不支持)SQL> explain select * from emp where dept_id+emp_id=1000 and salary>900;+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+| Id | Operation type                 | Name                 | Owner      | Rows     | Cost(%CPU)  | Partition info                 |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+|  0 | SELECT STATEMENT               |                      |            |          |             |                                ||* 1 |  TABLE ACCESS FULL             | EMP                  | TESTUSER   |        10|       47( 0)|                                |+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+Operation Information (identified by operation id):---------------------------------------------------   1 - Predicate : filter("EMP"."DEPT_ID"+"EMP"."EMP_ID" = 1000 AND "EMP"."SALARY" > 900)   -- Vastbase-- Having 并入 Where(不支持)vastbase=> explain SELECT * FROM emp where dept_id=100 HAVING salary > 5000;ERROR:  column "emp.emp_id" must appear in the GROUP BY clause or be used in an aggregate functionLINE 1: explain SELECT * FROM emp where dept_id=100 HAVING salary > ...
--去除冗余括號(支持)vastbase=> explain SELECT * FROM emp WHERE ((dept_id=2));                       QUERY PLAN-------------------------------------------------------- Seq Scan on emp  (cost=0.00..243.00 rows=106 width=44)   Filter: (dept_id = 2::number)
-- 常量傳遞(支持)vastbase=> explain select * from emp where dept_id=10 and emp_id=dept_id;                            QUERY PLAN------------------------------------------------------------------- Index Scan using emp_pk on emp  (cost=0.00..8.27 rows=1 width=44)   Index Cond: (emp_id = 10::number)   Filter: (dept_id = 10::number)   -- 消除死碼(支持)vastbase=> explain select * from emp where (0>1) or dept_id=10;                      QUERY PLAN------------------------------------------------------- Seq Scan on emp  (cost=0.00..243.00 rows=91 width=44)   Filter: (dept_id = 10::number)
-- 表達式計算(支持)vastbase=> explain select * from emp where dept_id=1+2;                      QUERY PLAN------------------------------------------------------- Seq Scan on emp  (cost=0.00..243.00 rows=91 width=44)   Filter: (dept_id = 3::number)
-- 等式變換(不支持)vastbase=> explain select * from emp where -dept_id=-10;                      QUERY PLAN------------------------------------------------------- Seq Scan on emp  (cost=0.00..268.00 rows=50 width=44)   Filter: ((- dept_id) = (-10)::number)
-- 不等式轉換(不支持)vastbase=> explain select * from emp where salary >1100 and salary>2000;                                       QUERY PLAN----------------------------------------------------------------------------------------- Index Scan using idx_emp_salary on emp  (cost=0.00..8.27 rows=1 width=44)   Index Cond: ((salary > 1100::double precision) AND (salary > 2000::double precision))
-- 謂詞傳遞閉包(不支持)vastbase=> explain select * from emp where emp_id>dept_id and dept_id>900;                         QUERY PLAN------------------------------------------------------------ Seq Scan on emp  (cost=0.00..268.00 rows=1 width=44)   Filter: ((emp_id > dept_id) AND (dept_id > 900::number))
-- 等價合取范式(支持)vastbase=> explain select * from emp where (0>1) and dept_id=10;                         QUERY PLAN------------------------------------------------------------ Result  (cost=0.00..218.00 rows=1 width=44)   One-Time Filter: false   ->  Seq Scan on emp  (cost=0.00..218.00 rows=1 width=44)
-- AND 操作符交換(支持)vastbase=> explain select * from emp where dept_id+emp_id=1000 and salary>900;                                      QUERY PLAN-------------------------------------------------------------------------------------- Seq Scan on emp  (cost=0.00..293.00 rows=45 width=44)   Filter: ((salary > 900::double precision) AND ((dept_id + emp_id) = 1000::number))

3. 邏輯優化—連接消除

在多表連接的過程中,查詢優化器可以找出多表連接的最優查詢執行計劃,這意味著多個表的最優的連接次序被確定。如果根據表的連接次序確定析取條件的優先判斷次序,存在加速判斷的可能(處于表達式后面的條件可能不用判斷了)。

1).優化規則

5.png5.png

2).數據庫支持情況

6.png6.png

3).數據庫測評

受篇幅限制,略去操作部分。

4. 邏輯優化—索引優化

如果語句中不僅包含有Select(選擇)、Project(投影)、Join(連接) 三種基礎操作,還有其他類操作(如分組等)。此時,優化器是可以根據索引進行一定的優化。

1).優化規則

7.png7.png

2).數據庫支持情況

8.png8.png

3).數據庫測評

受篇幅限制,略去操作部分。

責任編輯:武曉燕 來源: 韓鋒頻道
相關推薦

2025-04-08 07:30:40

數據庫對象索引

2025-03-27 07:30:28

2024-12-04 08:44:25

OS集中式數據庫

2025-01-09 07:30:49

SQL能力評測

2022-06-06 07:32:44

數據庫系統分布式

2012-02-23 23:33:37

開源memcached

2024-12-19 07:30:34

2024-12-10 07:30:46

2023-11-27 08:33:42

2024-12-05 07:31:16

2025-04-21 07:31:21

OB單機版數據庫

2023-08-22 14:20:21

2024-12-26 07:33:02

2015-07-28 09:44:38

集中式云數據加密安全漏洞

2022-03-29 14:28:03

架構安全設計

2019-11-07 11:21:21

安全軟件IT

2025-03-11 07:31:04

2025-08-19 01:55:00

React客戶端服務端

2009-07-02 19:24:50

安全管理Windows審計

2012-02-21 09:59:52

點贊
收藏

51CTO技術棧公眾號

亚洲午夜久久久影院| 一区二区三区国产精品| 国产精品亚洲精品| 男女性高潮免费网站| 亚洲三区欧美一区国产二区| 午夜精品久久久久久久久久 | 亚洲免费毛片| 欧美高清精品3d| 少妇av一区二区三区无码| 国产一区二区三区福利| 国产老女人精品毛片久久| 97视频在线观看免费| 无码人中文字幕| 精品中国亚洲| 欧美绝品在线观看成人午夜影视| 福利视频一区二区三区四区| h视频在线免费| gogogo免费视频观看亚洲一| 国产免费一区二区三区在线能观看 | 欧美激情一区二区三区蜜桃视频| 91视频在线免费观看| 91视频久久久| 亚洲国内精品| 另类色图亚洲色图| 日本成人午夜影院| 免费成人蒂法| 欧美一区二区精品久久911| 久久久久久久久久久久久国产精品| 国产最新在线| 久久精品欧美日韩| 国产在线精品一区| 国产免费不卡av| 日本欧美在线观看| 91精品国产高清| 久久久国产精华液| 91精品啪在线观看国产18| 在线播放国产一区二区三区| 捆绑凌虐一区二区三区| 欧美日韩午夜电影网| 欧美日韩精品欧美日韩精品一 | 亚洲精品午夜国产va久久成人| 99久久亚洲精品蜜臀| 亚洲深夜福利在线| 亚洲午夜久久久久久久久红桃| 99re8这里有精品热视频8在线| 制服丝袜av成人在线看| 奇米影视四色在线| 97成人超碰| 欧美中文字幕不卡| 日本888xxxx| 国精产品一区二区三区有限公司| 欧美日韩精品二区| 男人添女人下部高潮视频在观看| 在线中文字幕第一页| 1000精品久久久久久久久| 亚洲国产另类久久久精品极度| 蜜桃视频在线播放| 久久中文字幕电影| 欧美成人dvd在线视频| 日韩电影在线观看完整版| av电影天堂一区二区在线观看| 粉嫩av四季av绯色av第一区| 丰满人妻一区二区三区无码av| 国内精品伊人久久久久av一坑| 成人午夜激情网| 国产免费无遮挡| 国产福利不卡视频| 国产精品v欧美精品v日韩| 国产 日韩 欧美 综合| 成人丝袜视频网| 精品一区久久| 国产天堂素人系列在线视频| 国产欧美一区二区精品性| 五月天色一区| 欧美黄色激情| 亚洲视频一区在线| av片在线免费| 久草在线中文最新视频| 色婷婷亚洲精品| 国产一区亚洲二区三区| 日韩免费电影| 欧美精品三级日韩久久| 无码人妻一区二区三区在线视频| 在线日韩成人| 亚洲精品一区av在线播放| 性欧美精品中出| 欧美xxxxx视频| 欧美国产日韩一区二区| 九九精品免费视频| 麻豆国产精品官网| av资源站久久亚洲| 深夜福利视频一区| 国产精品欧美久久久久无广告| 麻豆传媒网站在线观看| 国产美女精品写真福利视频| 在线观看一区日韩| 三上悠亚 电影| 免费一区二区三区视频导航| 久久精品国产91精品亚洲| 久久亚洲国产成人精品性色| 视频一区视频二区中文| 亚洲iv一区二区三区| 少妇人妻精品一区二区三区| 国产精品视频线看| 欧美一级片免费播放| 日韩美女在线看免费观看| 欧美一级片在线| 成人国产精品久久久网站| 一级欧洲+日本+国产| 欧美做受高潮1| 精品人妻无码一区二区| 国产亚洲va综合人人澡精品| 久久久久久久9| jizz久久久久久| 亚洲第一视频网| 波兰性xxxxx极品hd| 国产一区导航| 99久久国产免费免费| seseavlu视频在线| 午夜精品福利一区二区三区蜜桃| 老司机久久精品| 免费观看久久av| 久久久欧美精品| 国产美女三级无套内谢| 亚洲国产精品99久久久久久久久| 老太脱裤让老头玩ⅹxxxx| 精品视频在线观看免费观看 | 欧美日韩久久久| 97超碰在线免费观看| 最新亚洲激情| 91福利视频导航| 日本网站在线免费观看视频| 色欧美88888久久久久久影院| av免费观看不卡| 国产精品chinese| 91福利视频导航| 在线中文字幕电影| 欧美一区二区三级| 91久久国产综合| 另类小说欧美激情| 日韩亚洲视频| 台湾成人免费视频| 国产一区二区三区在线观看视频| 91九色丨porny丨肉丝| 成人av网站在线| 日本手机在线视频| 精品午夜电影| 97视频免费看| 手机福利在线| 狠狠色狠色综合曰曰| 国产精品一区二区在线免费观看| 中文在线资源| 日韩精品福利在线| 日韩免费视频一区二区视频在线观看| 国产成人自拍网| 女女百合国产免费网站| 国产麻豆久久| 色偷偷av一区二区三区| 波多野结衣家庭主妇| 久久九九国产精品| 能在线观看的av网站| 国产伦理久久久久久妇女 | 在线一区av| 日韩激情av在线播放| 岛国av中文字幕| 久久久精品综合| 国产视频一区二区视频| 精品国产午夜| 91美女片黄在线观| 18加网站在线| 精品国产伦理网| 免费日韩一级片| 成人一级视频在线观看| 国产精品12345| 色橹橹欧美在线观看视频高清| 97在线免费观看视频| 日韩精品视频无播放器在线看 | 福利精品在线| 日韩在线视频中文字幕| 国产精品亚洲lv粉色| 亚洲柠檬福利资源导航| 无码人妻久久一区二区三区蜜桃| 好看的日韩av电影| 国产精品12| 玖玖在线播放| 日韩有码视频在线| 亚洲AV无码精品国产| 午夜电影一区二区三区| 伊人网伊人影院| 精品一区二区三区香蕉蜜桃| 超碰超碰超碰超碰超碰| 欧美18xxxx| 国产精品黄色av| 国产午夜精品久久久久免费视| 亚洲国产成人久久综合| 日韩一级片中文字幕| 国产精品久久久爽爽爽麻豆色哟哟| 奇米777在线| 99香蕉国产精品偷在线观看| 一区二区三区视频| 999久久精品| 国产精品v片在线观看不卡| 黄色网页在线观看| 亚洲成人激情图| 亚洲最大成人av| 五月天精品一区二区三区| 国产7777777| 国内成人自拍视频| 欧美日韩激情视频在线观看| 色偷偷综合网| 国产精品有限公司| 成人性片免费| 日本精品视频网站| 日韩av毛片| 一本大道久久加勒比香蕉| 亚洲精品无码久久久| 欧美日韩三级在线| 福利一区二区三区四区| 欧美国产激情一区二区三区蜜月| www.com日本| 蜜桃在线一区二区三区| 久章草在线视频| 激情成人亚洲| 五月天av影院| 欧美男同视频网| 精品国产91亚洲一区二区三区www| 国产成人精品一区二区三区视频 | 丝袜国产在线| 久久影院在线观看| 国产视频精品久久| 亚洲精品国偷自产在线99热| av av片在线看| 欧美精品日韩一本| av手机天堂网| 天天影视涩香欲综合网| 中文字幕在线有码| 中文字幕在线观看一区| 成年人免费观看视频网站| 成人av片在线观看| 中文字幕乱妇无码av在线| 亚洲激情自拍| 国产九色porny| 欧美国产91| 宅男一区二区三区| blacked蜜桃精品一区| 欧美日韩一区二| 麻豆一区二区| 国产精品有限公司| 99re91这里只有精品| 国产精品果冻传媒潘| 日韩欧美中文字幕一区二区三区| 91精品久久久久久久久青青 | 91麻豆精品秘密入口| 四虎国产精品免费久久| 国产精品极品在线| 深夜视频一区二区| 91精品久久久久久久久不口人| 亚洲精品.com| 国产精品色婷婷视频| 成人1区2区| 91久久久久久久久| 四虎国产精品永久在线国在线| 国产日产久久高清欧美一区| 成人在线观看免费播放| 成人信息集中地欧美| 玖玖玖电影综合影院| 川上优av一区二区线观看| 日韩一级视频| 国产有码在线一区二区视频| 亚洲免费一区| 亚洲自拍偷拍第一页| 深夜激情久久| 俄罗斯精品一区二区三区| 国产精品玖玖玖在线资源| 精品国产免费久久久久久尖叫| 老司机在线精品视频| 欧美成人第一区| 日韩www.| 亚洲小视频在线播放| 欧美涩涩网站| 欧美 国产 小说 另类| 免费观看成人av| 三日本三级少妇三级99| 国产成人av一区二区| 麻豆精品免费视频| 中文子幕无线码一区tr| 久久中文免费视频| 亚洲成av人片在线观看无码| www.亚洲激情| 欧美精品国产精品| 一级日韩一级欧美| 精品少妇一区二区三区免费观看| 欧美特级特黄aaaaaa在线看| 亚洲欧美激情一区| 美女写真理伦片在线看| 久久久久久国产免费| 中文日产幕无线码一区二区| 日韩av片电影专区| www.久久99| 精品乱色一区二区中文字幕| av永久不卡| 国产成人无码精品久久久性色| 日韩国产高清在线| 人妻精油按摩bd高清中文字幕| 成人免费高清视频| 黑人狂躁日本娇小| 黑人与娇小精品av专区| 亚洲图片在线播放| 国产午夜精品麻豆| 中国av在线播放| 国产精品久久久久免费a∨大胸| 韩日一区二区| 久久精品国产美女| 91精品国产视频| 日韩一级在线免费观看| 国产99久久久国产精品潘金| 精品人妻一区二区三区四区| 亚洲国产另类av| 夜夜嗨av禁果av粉嫩avhd| 亚洲欧美精品在线| 久草在线资源站资源站| 国产精品第一区| 一本色道久久综合亚洲精品酒店| 裸体裸乳免费看| 视频一区在线播放| 国产一区二区在线观看免费视频| 国产调教视频一区| 国产中文字幕免费| 69堂精品视频| 黄色片免费在线观看| 国产suv精品一区二区三区88区| 中文字幕av一区二区三区四区| 一区二区三区不卡在线| 亚洲欧美春色| 亚洲图片欧美另类| 亚洲色图制服丝袜| 国产精品嫩草影院精东| 伊人久久综合97精品| 一本大道色婷婷在线| 亚洲最大的av网站| 999国产精品永久免费视频app| 能在线观看的av| 99国内精品久久| 成年人午夜视频| 亚洲精品在线三区| 四虎亚洲成人| 俄罗斯精品一区二区| 欧美三级不卡| 一区二区三区四区影院| 亚洲影视在线播放| 精品国产乱码一区二区三 | a级国产乱理论片在线观看99| **女人18毛片一区二区| 五月天婷婷影视| 亚洲蜜臀av乱码久久精品| 国产精品热久久| 日韩亚洲精品视频| 麻豆精品国产| 国产一二三四区在线观看| 久久99精品久久久| 任你操精品视频| 欧美一级黄色录像| 九色91在线| 国产精品视频入口| 久久久精品日韩| 久久精品一区二区免费播放| 一本久久综合亚洲鲁鲁五月天| 成人性爱视频在线观看| 国产精品av在线| 成人情趣视频| 天天视频天天爽| 日韩理论片一区二区| www.激情五月| 久久精品国产精品| 国产精品视频3p| 欧美性大战久久久久xxx| 成人久久久精品乱码一区二区三区| 久久精品国产成人av| 亚洲男人av在线| 国产黄色一区| 国产美女永久无遮挡| 99热这里都是精品| 人人爽人人爽人人片av| 超碰97人人做人人爱少妇| 综合视频一区| 欧洲黄色一级视频| 中文字幕五月欧美| 精品人妻午夜一区二区三区四区 | 99一区二区| 校园春色综合网| 强制高潮抽搐sm调教高h| 欧美一区二区福利视频| 黄毛片在线观看| www.午夜色| 99久久久久久99| 国产精品传媒在线观看| 欧美精品国产精品日韩精品| 嫩草影视亚洲| 少妇性l交大片7724com| 日韩欧美亚洲成人|