2024-05-06 monetdb-逻辑优化-空值拒绝-记录

摘要:

2024-05-06 monetdb-空值拒绝-记录.

相关上下文:2022-10-12 mysql-外连接转内连接-空值拒绝-分析_mysql优化器什么时候会把外连接变成内连接-CSDN博客

参考:

Mysql 优化器之外连接消除笔记 - 简书

SQL优化--逻辑优化--外连接、嵌套连接与连接消除_数据库前沿资讯 | 和通数据库

MySQL之基于规则的优化特性(二) - 墨天轮

逻辑优化-空值拒绝

  1. 在外连接中,如果在连接条件里,存在将NULL值过滤掉的条件,则 将外连接转换为内连接。
  2. 所谓空值,指代的是特殊值NULL。
  3. 理解这个转换规则,需要明白连接的语义,以及外连接和内连接的区别。
  4. 从结果和关系代数上,都是非常清晰的逻辑。
  5. 那么为什么要转换为内连接呢? 答案自然是利用内连接的一些优化规则,例如只有在内连接时,才可以交换不同表的连接顺序。
  6. 本文以monetdb为例,再次展示空值拒绝的语义,以及以及空值拒绝对外连接转为内连接的具体的分析。

DDL:

代码文件: monetdb-dev/trunk/profill/proifill_null_reject.sql at main · adofsauron/monetdb-dev (github.com)

表结构和插入数据:

create table t1( a int, b int );
create table t2( a int, b int );
 
 
insert into t1(a,b) values(3,4);
insert into t1(a,b) values(5,6);
 
 
insert into t2(a,b) values(3,1);
insert into t2(a,b) values(7,2);

外连接-不加空值拒绝:

SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;

外连接-加空值拒绝:

SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;

等价的内连接:

SELECT * FROM  t1 INNER JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;

外连接-不加空值拒绝-分析:

查看执行计划:

PLAN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;

sql>PLAN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;
more>+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| rel                                                                                                                                                                                          |
+==============================================================================================================================================================================================+
| project (                                                                                                                                                                                    |
| | left outer join (                                                                                                                                                                          |
| | | table("sys"."t1") [ "t1"."a" UNIQUE MIN "3" MAX "5" NUNIQUES 2.000000, "t1"."b" UNIQUE MIN "4" MAX "6" NUNIQUES 2.000000 ] COUNT 2,                                                      |
| | | table("sys"."t2") [ "t2"."a" UNIQUE MIN "3" MAX "7" NUNIQUES 2.000000, "t2"."b" UNIQUE MIN "1" MAX "2" NUNIQUES 2.000000 ] COUNT 2                                                       |
| | ) [ ("t2"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "7") = ("t1"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5") ] COUNT 2                                                                    |
| ) [ "t1"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t1"."b" NUNIQUES 2.000000 MIN "4" MAX "6", "t2"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t2"."b" NUNIQUES 2.000000 MIN "1" MAX |
:  "2" ] COUNT 2                                                                                                                                                                               :
| push_project_down                      0 actions 1 usec                                                                                                                                      |
| merge_projects                         0 actions 0 usec                                                                                                                                      |
| push_project_up                        0 actions 0 usec                                                                                                                                      |
| split_project                          0 actions 1 usec                                                                                                                                      |
| remove_redundant_join                  0 actions 0 usec                                                                                                                                      |
| simplify_math                          0 actions 0 usec                                                                                                                                      |
| optimize_exps                          0 actions 1 usec                                                                                                                                      |
| optimize_select_and_joins_bottomup     0 actions 2 usec                                                                                                                                      |
| project_reduce_casts                   0 actions 0 usec                                                                                                                                      |
| optimize_projections                   0 actions 1 usec                                                                                                                                      |
| optimize_joins                         0 actions 2 usec                                                                                                                                      |
| join_order                             0 actions 6 usec                                                                                                                                      |
| optimize_semi_and_anti                 0 actions 1 usec                                                                                                                                      |
| optimize_select_and_joins_topdown      0 actions 3 usec                                                                                                                                      |
| dce                                    0 actions 5 usec                                                                                                                                      |
| push_func_and_select_down              0 actions 1 usec                                                                                                                                      |
| get_statistics                         0 actions 55 usec                                                                                                                                     |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
23 tuples

查看列的物理执行:

EXPLAIN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;

sql>EXPLAIN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;
more>+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mal                                                                                                                                                                            |
+================================================================================================================================================================================+
| function user.main():void;                                                                                                                                                     |
|     X_1:void := querylog.define("explain\nselect * from t1 left join t2 on t2.a = t1.a;":str, "default_pipe":str, 52:int);                                                     |
| barrier X_140:bit := language.dataflow();                                                                                                                                      |
|     X_4:int := sql.mvc();                                                                                                                                                      |
|     C_5:bat[:oid] := sql.tid(X_4:int, "sys":str, "t1":str);                                                                                                                    |
|     X_8:bat[:int] := sql.bind(X_4:int, "sys":str, "t1":str, "a":str, 0:int);                                                                                                   |
|     X_15:bat[:int] := sql.bind(X_4:int, "sys":str, "t1":str, "b":str, 0:int);                                                                                                  |
|     C_20:bat[:oid] := sql.tid(X_4:int, "sys":str, "t2":str);                                                                                                                   |
|     X_22:bat[:int] := sql.bind(X_4:int, "sys":str, "t2":str, "a":str, 0:int);                                                                                                  |
|     X_28:bat[:int] := sql.bind(X_4:int, "sys":str, "t2":str, "b":str, 0:int);                                                                                                  |
|     X_34:bat[:int] := algebra.projection(C_5:bat[:oid], X_8:bat[:int]);                                                                                                        |
|     X_35:bat[:int] := algebra.projection(C_5:bat[:oid], X_15:bat[:int]);                                                                                                       |
|     X_142:void := language.pass(C_5:bat[:oid]);                                                                                                                                |
|     X_36:bat[:int] := algebra.projection(C_20:bat[:oid], X_22:bat[:int]);                                                                                                      |
|     (X_38:bat[:oid], X_39:bat[:oid]) := algebra.join(X_34:bat[:int], X_36:bat[:int], nil:BAT, nil:BAT, false:bit, nil:lng);                                                    |
|     C_44:bat[:oid] := bat.mirror(X_34:bat[:int]);                                                                                                                              |
|     C_45:bat[:oid] := algebra.difference(C_44:bat[:oid], X_38:bat[:oid], nil:BAT, nil:BAT, false:bit, false:bit, nil:lng);                                                     |
|     X_46:bat[:int] := algebra.projection(X_38:bat[:oid], X_34:bat[:int]);                                                                                                      |
|     X_47:bat[:int] := bat.new(nil:int);                                                                                                                                        |
|     X_49:bat[:int] := bat.append(X_47:bat[:int], X_46:bat[:int], true:bit);                                                                                                    |
|     X_51:bat[:int] := algebra.projection(C_45:bat[:oid], X_34:bat[:int]);                                                                                                      |
|     X_143:void := language.pass(X_34:bat[:int]);                                                                                                                               |
|     X_52:bat[:int] := bat.append(X_49:bat[:int], X_51:bat[:int], true:bit);                                                                                                    |
|     X_53:bat[:int] := algebra.projection(X_38:bat[:oid], X_35:bat[:int]);                                                                                                      |
|     X_144:void := language.pass(X_38:bat[:oid]);                                                                                                                               |
|     X_54:bat[:int] := bat.new(nil:int);                                                                                                                                        |
|     X_55:bat[:int] := bat.append(X_54:bat[:int], X_53:bat[:int], true:bit);                                                                                                    |
|     X_56:bat[:int] := algebra.projection(C_45:bat[:oid], X_35:bat[:int]);                                                                                                      |
|     X_145:void := language.pass(X_35:bat[:int]);                                                                                                                               |
|     X_57:bat[:int] := bat.append(X_55:bat[:int], X_56:bat[:int], true:bit);                                                                                                    |
|     X_58:bat[:int] := algebra.projection(X_39:bat[:oid], X_36:bat[:int]);                                                                                                      |
|     X_146:void := language.pass(X_36:bat[:int]);                                                                                                                               |
|     X_59:bat[:int] := bat.new(nil:int);                                                                                                                                        |
|     X_60:bat[:int] := bat.append(X_59:bat[:int], X_58:bat[:int], true:bit);                                                                                                    |
|     X_62:bat[:int] := algebra.project(C_45:bat[:oid], nil:int);                                                                                                                |
|     X_63:bat[:int] := bat.append(X_60:bat[:int], X_62:bat[:int], true:bit);                                                                                                    |
|     X_64:bat[:int] := algebra.projectionpath(X_39:bat[:oid], C_20:bat[:oid], X_28:bat[:int]);                                                                                  |
|     X_147:void := language.pass(X_39:bat[:oid]);                                                                                                                               |
|     X_148:void := language.pass(C_20:bat[:oid]);                                                                                                                               |
|     X_65:bat[:int] := bat.new(nil:int);                                                                                                                                        |
|     X_67:bat[:int] := bat.append(X_65:bat[:int], X_64:bat[:int], true:bit);                                                                                                    |
|     X_70:bat[:int] := algebra.project(C_45:bat[:oid], nil:int);                                                                                                                |
|     X_149:void := language.pass(C_45:bat[:oid]);                                                                                                                               |
|     X_71:bat[:int] := bat.append(X_67:bat[:int], X_70:bat[:int], true:bit);                                                                                                    |
|     X_73:bat[:str] := bat.pack(".t1":str, ".t1":str, ".t2":str, ".t2":str);                                                                                                    |
|     X_74:bat[:str] := bat.pack("a":str, "b":str, "a":str, "b":str);                                                                                                            |
|     X_75:bat[:str] := bat.pack("int":str, "int":str, "int":str, "int":str);                                                                                                    |
|     X_76:bat[:int] := bat.pack(32:int, 32:int, 32:int, 32:int);                                                                                                                |
|     X_77:bat[:int] := bat.pack(0:int, 0:int, 0:int, 0:int);                                                                                                                    |
| exit X_140:bit;                                                                                                                                                                |
|     X_72:int := sql.resultSet(X_73:bat[:str], X_74:bat[:str], X_75:bat[:str], X_76:bat[:int], X_77:bat[:int], X_52:bat[:int], X_57:bat[:int], X_63:bat[:int], X_71:bat[:int]); |
| end user.main;                                                                                                                                                                 |
| # optimizer.inline(0:int, 1:lng)                                                                                                                                               |
| # optimizer.remap(0:int, 2:lng)                                                                                                                                                |
| # optimizer.costModel(1:int, 2:lng)                                                                                                                                            |
| # optimizer.coercions(0:int, 3:lng)                                                                                                                                            |
| # optimizer.aliases(2:int, 6:lng)                                                                                                                                              |
| # optimizer.evaluate(0:int, 5:lng)                                                                                                                                             |
| # optimizer.emptybind(4:int, 8:lng)                                                                                                                                            |
| # optimizer.deadcode(4:int, 9:lng)                                                                                                                                             |
| # optimizer.pushselect(0:int, 3:lng)                                                                                                                                           |
| # optimizer.aliases(4:int, 5:lng)                                                                                                                                              |
| # optimizer.for(0:int, 0:lng)                                                                                                                                                  |
| # optimizer.dict(0:int, 3:lng)                                                                                                                                                 |
| # optimizer.mitosis(0:int, 10:lng)                                                                                                                                             |
| # optimizer.mergetable(0:int, 11:lng)                                                                                                                                          |
| # optimizer.bincopyfrom(0:int, 1:lng)                                                                                                                                          |
| # optimizer.aliases(0:int, 0:lng)                                                                                                                                              |
| # optimizer.constants(3:int, 7:lng)                                                                                                                                            |
| # optimizer.commonTerms(0:int, 7:lng)                                                                                                                                          |
| # optimizer.projectionpath(1:int, 24:lng)                                                                                                                                      |
| # optimizer.deadcode(1:int, 6:lng)                                                                                                                                             |
| # optimizer.matpack(0:int, 1:lng)                                                                                                                                              |
| # optimizer.reorder(1:int, 7:lng)                                                                                                                                              |
| # optimizer.dataflow(1:int, 15:lng)                                                                                                                                            |
| # optimizer.querylog(0:int, 1:lng)                                                                                                                                             |
| # optimizer.multiplex(0:int, 0:lng)                                                                                                                                            |
| # optimizer.generator(0:int, 2:lng)                                                                                                                                            |
| # optimizer.candidates(1:int, 1:lng)                                                                                                                                           |
| # optimizer.deadcode(0:int, 4:lng)                                                                                                                                             |
| # optimizer.postfix(0:int, 5:lng)                                                                                                                                              |
| # optimizer.wlc(0:int, 1:lng)                                                                                                                                                  |
| # optimizer.profiler(0:int, 0:lng)                                                                                                                                             |
| # optimizer.garbageCollector(1:int, 14:lng)                                                                                                                                    |
| # optimizer.total(32:int, 212:lng)                                                                                                                                             |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
85 tuples

执行结果:

sql>SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;
+------+------+------+------+
| a    | b    | a    | b    |
+======+======+======+======+
|    3 |    4 |    3 |    1 |
|    5 |    6 | null | null |
+------+------+------+------+
2 tuples

分析:

  1. 结果中存在空值,无法使用空值拒绝的逻辑转换规则
  2. 执行计划是使用的 left outer join
    1. 条件是:
    2. [ "t1"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t1"."b" NUNIQUES 2.000000 MIN "4" MAX "6", "t2"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t2"."b" NUNIQUES 2.000000 MIN "1" MAX |
      :  "2" ]

外连接-加空值拒绝:

查看执行计划:

sql>PLAN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;more>
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| rel                                                                                                                                                                                          |
+==============================================================================================================================================================================================+
| project (                                                                                                                                                                                    |
| | join (                                                                                                                                                                                     |
| | | select (                                                                                                                                                                                 |
| | | | table("sys"."t2") [ "t2"."a" UNIQUE MIN "3" MAX "7" NUNIQUES 2.000000, "t2"."b" UNIQUE MIN "1" MAX "2" NUNIQUES 2.000000 ] COUNT 2                                                     |
| | | ) [ ("t2"."b" UNIQUE NUNIQUES 2.000000 MIN "1" MAX "2") < (int(32) "5") ] COUNT 2,                                                                                                       |
| | | table("sys"."t1") [ "t1"."a" UNIQUE MIN "3" MAX "5" NUNIQUES 2.000000, "t1"."b" UNIQUE MIN "4" MAX "6" NUNIQUES 2.000000 ] COUNT 2                                                       |
| | ) [ ("t2"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "7") = ("t1"."a" UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5") ] COUNT 2                                                                    |
| ) [ "t1"."a" NOT NULL UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t1"."b" NUNIQUES 2.000000 MIN "4" MAX "6", "t2"."a" NOT NULL UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t2"."b" NOT NULL NU |
: NIQUES 2.000000 MIN "1" MAX "2" ] COUNT 2                                                                                                                                                    :
| split_select                           0 actions 1 usec                                                                                                                                      |
| push_project_down                      0 actions 2 usec                                                                                                                                      |
| merge_projects                         0 actions 1 usec                                                                                                                                      |
| push_project_up                        2 actions 15 usec                                                                                                                                     |
| split_project                          0 actions 2 usec                                                                                                                                      |
| remove_redundant_join                  0 actions 1 usec                                                                                                                                      |
| simplify_math                          0 actions 1 usec                                                                                                                                      |
| optimize_exps                          0 actions 4 usec                                                                                                                                      |
| optimize_select_and_joins_bottomup     0 actions 6 usec                                                                                                                                      |
| project_reduce_casts                   0 actions 0 usec                                                                                                                                      |
| optimize_projections                   0 actions 2 usec                                                                                                                                      |
| optimize_joins                         1 actions 10 usec                                                                                                                                     |
| join_order                             0 actions 22 usec                                                                                                                                     |
| optimize_semi_and_anti                 0 actions 3 usec                                                                                                                                      |
| optimize_select_and_joins_topdown      2 actions 7 usec                                                                                                                                      |
| dce                                    0 actions 9 usec                                                                                                                                      |
| push_func_and_select_down              0 actions 4 usec                                                                                                                                      |
| get_statistics                         0 actions 75 usec                                                                                                                                     |
| final_optimization_loop                0 actions 2 usec                                                                                                                                      |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
27 tuples

查看列的物理执行:

sql>
EXPLAIN
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;sql>more>
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mal                                                                                                                                                                            |
+================================================================================================================================================================================+
| function user.main():void;                                                                                                                                                     |
|     X_1:void := querylog.define("explain\nselect * from t1 left join t2 on t2.a = t1.a where t2.b < 5;":str, "default_pipe":str, 34:int);                                      |
| barrier X_122:bit := language.dataflow();                                                                                                                                      |
|     X_4:int := sql.mvc();                                                                                                                                                      |
|     C_5:bat[:oid] := sql.tid(X_4:int, "sys":str, "t2":str);                                                                                                                    |
|     X_8:bat[:int] := sql.bind(X_4:int, "sys":str, "t2":str, "a":str, 0:int);                                                                                                   |
|     X_15:bat[:int] := sql.bind(X_4:int, "sys":str, "t2":str, "b":str, 0:int);                                                                                                  |
|     C_22:bat[:oid] := algebra.thetaselect(X_15:bat[:int], C_5:bat[:oid], 5:int, "<":str);                                                                                      |
|     C_24:bat[:oid] := sql.tid(X_4:int, "sys":str, "t1":str);                                                                                                                   |
|     X_27:bat[:int] := sql.bind(X_4:int, "sys":str, "t1":str, "a":str, 0:int);                                                                                                  |
|     X_34:bat[:int] := sql.bind(X_4:int, "sys":str, "t1":str, "b":str, 0:int);                                                                                                  |
|     X_39:bat[:int] := algebra.projection(C_22:bat[:oid], X_8:bat[:int]);                                                                                                       |
|     X_41:bat[:int] := algebra.projection(C_24:bat[:oid], X_27:bat[:int]);                                                                                                      |
|     (X_43:bat[:oid], X_44:bat[:oid]) := algebra.join(X_39:bat[:int], X_41:bat[:int], nil:BAT, nil:BAT, false:bit, nil:lng);                                                    |
|     X_49:bat[:int] := algebra.projection(X_43:bat[:oid], X_39:bat[:int]);                                                                                                      |
|     X_124:void := language.pass(X_39:bat[:int]);                                                                                                                               |
|     X_50:bat[:int] := algebra.projectionpath(X_43:bat[:oid], C_22:bat[:oid], X_15:bat[:int]);                                                                                  |
|     X_125:void := language.pass(X_43:bat[:oid]);                                                                                                                               |
|     X_126:void := language.pass(C_22:bat[:oid]);                                                                                                                               |
|     X_127:void := language.pass(X_15:bat[:int]);                                                                                                                               |
|     X_51:bat[:int] := algebra.projection(X_44:bat[:oid], X_41:bat[:int]);                                                                                                      |
|     X_128:void := language.pass(X_41:bat[:int]);                                                                                                                               |
|     X_52:bat[:int] := algebra.projectionpath(X_44:bat[:oid], C_24:bat[:oid], X_34:bat[:int]);                                                                                  |
|     X_129:void := language.pass(X_44:bat[:oid]);                                                                                                                               |
|     X_130:void := language.pass(C_24:bat[:oid]);                                                                                                                               |
|     X_54:bat[:str] := bat.pack("sys.t1":str, "sys.t1":str, "sys.t2":str, "sys.t2":str);                                                                                        |
|     X_55:bat[:str] := bat.pack("a":str, "b":str, "a":str, "b":str);                                                                                                            |
|     X_56:bat[:str] := bat.pack("int":str, "int":str, "int":str, "int":str);                                                                                                    |
|     X_57:bat[:int] := bat.pack(32:int, 32:int, 32:int, 32:int);                                                                                                                |
|     X_58:bat[:int] := bat.pack(0:int, 0:int, 0:int, 0:int);                                                                                                                    |
| exit X_122:bit;                                                                                                                                                                |
|     X_53:int := sql.resultSet(X_54:bat[:str], X_55:bat[:str], X_56:bat[:str], X_57:bat[:int], X_58:bat[:int], X_51:bat[:int], X_52:bat[:int], X_49:bat[:int], X_50:bat[:int]); |
| end user.main;                                                                                                                                                                 |
| # optimizer.inline(0:int, 2:lng)                                                                                                                                               |
| # optimizer.remap(0:int, 2:lng)                                                                                                                                                |
| # optimizer.costModel(1:int, 2:lng)                                                                                                                                            |
| # optimizer.coercions(0:int, 2:lng)                                                                                                                                            |
| # optimizer.aliases(1:int, 4:lng)                                                                                                                                              |
| # optimizer.evaluate(0:int, 4:lng)                                                                                                                                             |
| # optimizer.emptybind(4:int, 6:lng)                                                                                                                                            |
| # optimizer.deadcode(4:int, 5:lng)                                                                                                                                             |
| # optimizer.pushselect(0:int, 8:lng)                                                                                                                                           |
| # optimizer.aliases(4:int, 3:lng)                                                                                                                                              |
| # optimizer.for(0:int, 1:lng)                                                                                                                                                  |
| # optimizer.dict(0:int, 2:lng)                                                                                                                                                 |
| # optimizer.mitosis(0:int, 7:lng)                                                                                                                                              |
| # optimizer.mergetable(0:int, 7:lng)                                                                                                                                           |
| # optimizer.bincopyfrom(0:int, 1:lng)                                                                                                                                          |
| # optimizer.aliases(0:int, 0:lng)                                                                                                                                              |
| # optimizer.constants(3:int, 9:lng)                                                                                                                                            |
| # optimizer.commonTerms(0:int, 5:lng)                                                                                                                                          |
| # optimizer.projectionpath(2:int, 7:lng)                                                                                                                                       |
| # optimizer.deadcode(2:int, 3:lng)                                                                                                                                             |
| # optimizer.matpack(0:int, 1:lng)                                                                                                                                              |
| # optimizer.reorder(1:int, 4:lng)                                                                                                                                              |
| # optimizer.dataflow(1:int, 12:lng)                                                                                                                                            |
| # optimizer.querylog(0:int, 0:lng)                                                                                                                                             |
| # optimizer.multiplex(0:int, 1:lng)                                                                                                                                            |
| # optimizer.generator(0:int, 1:lng)                                                                                                                                            |
| # optimizer.candidates(1:int, 1:lng)                                                                                                                                           |
| # optimizer.deadcode(0:int, 2:lng)                                                                                                                                             |
| # optimizer.postfix(0:int, 3:lng)                                                                                                                                              |
| # optimizer.wlc(0:int, 1:lng)                                                                                                                                                  |
| # optimizer.profiler(0:int, 0:lng)                                                                                                                                             |
| # optimizer.garbageCollector(1:int, 7:lng)                                                                                                                                     |
| # optimizer.total(32:int, 154:lng)                                                                                                                                             |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
66 tuples

执行结果:

sql>SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;
+------+------+------+------+
| a    | b    | a    | b    |
+======+======+======+======+
|    3 |    4 |    3 |    1 |
+------+------+------+------+
1 tuple

分析:

  1. 添加了条件 WHERE t2.b < 5,连接的结果中,不可能再存在NULL, 也就是隐含了NOT  NULL的条件,对外连接进行转换成内连接
  2. 连接方式直接变成了 join, 也就是inner join:
    1. 连接条件变为如下,注意额外添加的NOT NULL的条件
    2. [ "t1"."a" NOT NULL UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t1"."b" NUNIQUES 2.000000 MIN "4" MAX "6", "t2"."a" NOT NULL UNIQUE NUNIQUES 2.000000 MIN "3" MAX "5", "t2"."b" NOT NULL NU |
      : NIQUES 2.000000 MIN "1" MAX "2" ]

等价于内连接:

执行结果:

sql>SELECT * FROM  t1 INNER JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;
+------+------+------+------+
| a    | b    | a    | b    |
+======+======+======+======+
|    3 |    4 |    3 |    1 |
+------+------+------+------+
1 tuple

对比mysql8中的空值拒绝:

查询计划-查询树结构:

explain format=tree
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;

 -> Inner hash join (t1.a = t2.a)  (cost=0.90 rows=1)
    -> Table scan on t1  (cost=0.35 rows=2)
    -> Hash
        -> Filter: (t2.b < 5)  (cost=0.45 rows=1)
            -> Table scan on t2  (cost=0.45 rows=2)

查询代价-json结构:

explain format=json
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5 \G

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "0.90"
    },
    "nested_loop": [
      {
        "table": {
          "table_name": "t2",
          "access_type": "ALL",
          "rows_examined_per_scan": 2,
          "rows_produced_per_join": 1,
          "filtered": "50.00",
          "cost_info": {
            "read_cost": "0.35",
            "eval_cost": "0.10",
            "prefix_cost": "0.45",
            "data_read_per_join": "16"
          },
          "used_columns": [
            "a",
            "b"
          ],
          "attached_condition": "(`d3`.`t2`.`b` < 5)"
        }
      },
      {
        "table": {
          "table_name": "t1",
          "access_type": "ALL",
          "rows_examined_per_scan": 2,
          "rows_produced_per_join": 1,
          "filtered": "50.00",
          "using_join_buffer": "hash join",
          "cost_info": {
            "read_cost": "0.25",
            "eval_cost": "0.10",
            "prefix_cost": "0.90",
            "data_read_per_join": "16"
          },
          "used_columns": [
            "a",
            "b"
          ],
          "attached_condition": "(`d3`.`t1`.`a` = `d3`.`t2`.`a`)"
        }
      }
    ]
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/595538.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python ArcPy批量将大量栅格文件的投影坐标系转为地理坐标系

本文介绍基于Python语言中的ArcPy模块&#xff0c;批量将多个遥感影像由投影坐标系转为地理坐标系的方法。 在之前的文章中&#xff0c;我们介绍过将单独1景遥感影像的投影坐标系转为地理坐标系的方法&#xff0c;大家可以参考文章投影坐标系转为地理坐标系&#xff1a;GDAL命令…

Voice Conversion、DreamScene、X-SLAM、Panoptic-SLAM、DiffMap、TinySeg

本文首发于公众号&#xff1a;机器感知 Voice Conversion、DreamScene、X-SLAM、Panoptic-SLAM、DiffMap、TinySeg Converting Anyones Voice: End-to-End Expressive Voice Conversion with a Conditional Diffusion Model Expressive voice conversion (VC) conducts speak…

【爬虫】爬取A股数据写入数据库(一)

1. 对东方财富官网的分析 步骤&#xff1a; 通过刷新网页&#xff0c;点击等操作&#xff0c;我们发现https://datacenter-web.eastmoney.com/api/data/v1/get?请求后面带着一些参数即可以获取到相应数据。我们使用python来模拟这个请求即可。 我们以如下选择的页面为切入点…

滑动窗口 | 1652. 拆炸弹 |LeetCode

文章目录 题目介绍暴力(可以过力扣竟然。不愧是简单题)&#xff1a;滑动窗口 祝你天天开心 题目介绍 你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每…

关系型数据库MySql分库分表带来的问题以及解决方案

水平分表 水平分表是什么&#xff1f; 将一张表横向拆分为多张表&#xff0c;拆分的表&#xff0c;依然在同一个库中。 例如&#xff0c;user表有400w条记录&#xff0c;将user表拆分成4张表&#xff0c;每张表100w条记录。拆分后的表名&#xff0c;分别叫做user_0、user1、u…

内网用户是如何连接上互联网的?详解NAT网络地址转换技术

背景 https://blog.csdn.net/weixin_43972437/article/details/107344633 不知道你有没有过困惑&#xff0c;都说现在 ipv4 地址耗尽了&#xff0c;但是我们为什么还能上网呢&#xff1f;原来这都要归功于 NAT 网络地址转换技术。 比如我们接入了中国移动的宽带&#xff0c;宽…

重学SpringBoot3-SPI机制

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SPI机制 什么是 SPI&#xff1f;Spring Boot 中的 SPI 机制spring.factories 文件自动配置的实现启动流程中的作用 SPI实际应用步骤 1: 新建模块步骤 2:…

扩展学习|一文读懂知识图谱

一、知识图谱的技术实现流程及相关应用 文献来源&#xff1a;曹倩,赵一鸣.知识图谱的技术实现流程及相关应用[J].情报理论与实践,2015, 38(12):127-132. &#xff08;一&#xff09;知识图谱的特征及功能 知识图谱是为了适应新的网络信息环境而产生的一种语义知识组织和服务的方…

HarmonyOS开发案例:【卡片二级联动】

1 卡片介绍 使用ArkTS语言&#xff0c;实现一个导航与内容二级联动的效果。 2 标题 二级联动&#xff08;ArkTS&#xff09; 3 介绍 介绍了如何基于List组件实现一个导航和内容的二级联动效果。样例主要包含以下功能&#xff1a; 切换左侧导航&#xff0c;右侧滚动到对应…

自定义类型②③——联合体和枚举

自定义类型②③——联合体和枚举 1.联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员结构体和联合体的对比1.4 联合体大小的计算1.5 联合体的应用①1.5 联合体的应用② 2. 枚举2.1 枚举类型的声明2.2 枚举类型的特点2.3 枚举的优点 1.联合体 1.1 联合体类型的声明 关…

Python sqlite3库 实现 数据库基础及应用 输入地点,可输出该地点的爱国主义教育基地名称和批次的查询结果。

目录 【第11次课】实验十数据库基础及应用1-查询 要求: 提示: 运行结果&#xff1a; 【第11次课】实验十数据库基础及应用1-查询 声明&#xff1a;著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 1.简答题 数据库文件Edu_Base.db&#…

有什么方便的教学口语软件?6个软件教你快速练习口语

有什么方便的教学口语软件&#xff1f;6个软件教你快速练习口语 以下是六个方便实用的教学口语软件&#xff0c;它们可以帮助您快速练习口语&#xff1a; AI外语陪练: 这是一款知名的语言学习软件&#xff0c;提供多种语言的口语练习课程。它采用沉浸式的学习方法&#xff0…

【数字图像处理笔记】Matlab实现图像平滑算法 均值-中值-高斯滤波 (三)

&#x1f48c; 所属专栏&#xff1a;【数字图像处理笔记】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x…

jetson实操(二):jetson nano发送短信到指定用户

文章目录 一、准备工作二、代码实现 一、准备工作 腾讯云网址&#xff1a;点击 注&#xff1a;需先申请“短信签名”和“短信正文”&#xff0c;按照要求填写申请即可&#xff0c;腾讯云的审核效率还是很快的&#xff0c;一般在1-2个小时内就会有结果&#xff0c;链接&…

2024-2034年,量子密码市场年增长率将达29.3%

Visiongain发布了一份新报告&#xff0c;题为《2024-2034年量子密码市场报告》&#xff1a;按组件&#xff08;软件、硬件&#xff09;、软件&#xff08;加密算法、密钥管理解决方案等&#xff09;、硬件&#xff08;量子密钥分发&#xff08;QKD&#xff09;设备、量子随机数…

CkickHouse JDBC 使用整理

1. pom 引入 <dependency><groupId>com.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.4.6</version></dependency><dependency><groupId>org.roaringbitmap</groupId><arti…

BeautifulSoup库TapTap评论爬虫

最近在写关于评论数据主题建模和情感分析的作业&#xff0c;本来想用八爪鱼直接爬TapTap的评论数据&#xff0c;但是自动识别网页总是定位错误&#xff0c;还是回归BeautifulSoup和Request来进行评论内容的爬取&#xff0c;具体操作步骤如下 导入所需的库 import re import r…

定制旁通式孔板流量计需要哪些技术参数

旁通式孔板流量计又称桥式孔板流量计&#xff0c;本产品含有直管&#xff0c;直管中安装有孔板&#xff0c;该孔板两侧的直管壁上分别设置一个测量管&#xff0c;其特征是&#xff1a;所述直管和一个桥管并联式连接&#xff0c;二者内管相互连通&#xff0c;并且所述直管和桥管…

mars3d的config,json文件配置谷歌影像地图的tilingScheme属性

mars3d的config,json文件配置tilingScheme属性说明&#xff1a; 1.cesium加载谷歌影像地图的时候需要配置tilingScheme参数&#xff0c;如以下代码&#xff1a; var viewer new Cesium.Viewer("cesiumContainer", { animation: false, //是否显示动画控件 baseLaye…

64位Office API声明语句第118讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…
最新文章