ToprowDB Dynamic Server 查询优化技术---子查询优化--01-2

2022-03-30 00:00:00 查询 执行 优化 计划 可以看出

在ToprowDB和MySQL执行同样的查询,用WHERE条件使得子查询为相关子查询,即前面的S4语句:

SELECT * FROM t3 WHERE a3 IN (SELECT a1 FROM t1 WHERE b1=b3);

ToprowDB的查询执行计划如下:

Estimated Cost: 4

Estimated # of Rows Returned: 1

1) informix.t3: SEQUENTIAL SCAN


2) informix.t1: INDEX PATH


Filters: informix.t1.b1 = informix.t3.b3

(1) Index Name: informix. 102_7

Index Keys: a1 (Serial, fragments: ALL)

Lower Index Filter: informix.t3.a3 = informix.t1.a1

NESTED LOOP JOIN





Query statistics:

-----------------

Table map :

----------------------------

Internal name Table name

----------------------------

t1 t3

t2 t1

type table rows_prod est_rows rows_scan time est_cost

-------------------------------------------------------------------

scan t1 6 1 6 00:00.00 2

type table rows_prod est_rows rows_scan time est_cost

-------------------------------------------------------------------

scan t2 3 1 3 00:00.01 0

type rows_prod est_rows time est_cost

-------------------------------------------------

nljoin 3 1 00:00.02 4

从查询执行计划可以看出,子查询已经被消除,变为了两表的嵌套循环连接,这说明ToprowDB对此类的子查询进行了优化。看到这里,Informix迷们该常舒一口气了吧,Informix子查询总算没有那么差,是吧?^_^

PostgreSQL的查询执行计划如下:

postgres=# explain SELECT * FROM t3 WHERE a3 IN (SELECT a1 FROM t1 WHERE b1=b3);

QUERY PLAN

------------------------------------------------------------

Seq Scan on t3 (cost=0.00..36271.00 rows=1020 width=12)

Filter: (SubPlan 1)

SubPlan 1

-> Seq Scan on t1 (cost=0.00..35.50 rows=10 width=4)

Filter: (b1 = t3.b3)

从查询执行计划可以看出,子查询没有被消除,这说明PosatgreSQL对此类的子查询不能优化,这是因为PosatgreSQL此处不支持对相关子查询的优化。

MySQL的查询执行计划如下:

mysql> explain SELECT * FROM t3 WHERE a3 IN (SELECT a1 FROM t1 WHERE b1=b3);

+----+-------------+-------+------+------+-------------+

| id | select_type | table | type | key | Extra |

+----+-------------+-------+------+------+-------------+

| 1 | SIMPLE | t1 | ALL | NULL | Using where |

| 1 | SIMPLE | t3 | ref | a3 | Using where |

+----+-------------+-------+------+------+-------------+

从查询执行计划可以看出,子查询已经被消除,变为了两表的嵌套循环连接,这说明MySQL对此类的子查询进行了优化。比较上面PostgreSQL的例子,我们可以发现,IN子查询的为非相关子查询的时候,MySQL也可以支持优化。

看到这里,MySQL迷们会继续兴高采烈,MySQL子查询优化很强,是吧?^_^

3.3 继续深入分析--相关子查询,不带有索引键
细心的读者可以发现,上一节中,我们选取的例子,都是相关子查询,而且,子查询左表达式的对象是一个索引列(a3列上存在索引),ToprowDB和MySQL优化器的能够对这样的子查询进行优化。

现在,我们修改SQL语句如下,注意变化的部分:

SELECT * FROM t3 WHERE b3 IN (SELECT b1 FROM t1 WHERE a1=a3);

ToprowDB的查询执行计划如下:

Estimated Cost: 4

Estimated # of Rows Returned: 1

1) informix.t3: SEQUENTIAL SCAN

2) informix.t1: INDEX PATH //t1表上执行了索引扫描,但注意是子查询中的表

Filters: informix.t3.b3 = informix.t1.b1

(1) Index Name: informix. 102_7 //索引被上拉之后,执行了索引扫描,

Index Keys: a1 (Serial, fragments: ALL)

Lower Index Filter: informix.t1.a1 = informix.t3.a3

NESTED LOOP JOIN

Query statistics:

-----------------

Table map :

----------------------------

Internal name Table name

----------------------------

t1 t3

t2 t1


type table rows_prod est_rows rows_scan time est_cost

-------------------------------------------------------------------

scan t1 6 1 6 00:00.00 2


type table rows_prod est_rows rows_scan time est_cost

-------------------------------------------------------------------

scan t2 3 1 3 00:00.00 0

type rows_prod est_rows time est_cost

-------------------------------------------------

nljoin 3 1 00:00.00 4

从查询执行计划可以看出,子查询已经被消除,变为了两表的嵌套循环连接,这说明ToprowDB对此类的子查询进行了优化。当我们再次感受到ToprowDB的子查询优化技术似乎不弱的时候,可以再看看PostgreSQL和MySQL的执行计划。

PostgreSQL的查询执行计划如下:

postgres=# explain SELECT * FROM t3 WHERE b3 IN (SELECT b1 FROM t1 WHERE a1=a3);

QUERY PLAN

----------------------------------------------------------------------------

Seq Scan on t3 (cost=0.00..8527.00 rows=1020 width=12)

Filter: (SubPlan 1)

SubPlan 1

-> Index Scan using t1_a1_key on t1 (cost=0.15..8.17 rows=1 width=4)

Index Cond: (a1 = t3.a3)

从查询执行计划可以看出,子查询没有被消除。

MySQL的查询执行计划如下:

mysql> explain SELECT * FROM t3 WHERE b3 IN (SELECT b1 FROM t1 WHERE a1=a3);

+----+-------------+-------+------+------+-------------+

| id | select_type | table | type | key | Extra |

+----+-------------+-------+------+------+-------------+

| 1 | SIMPLE | t1 | ALL | NULL | Using where |

| 1 | SIMPLE | t3 | ref | a3 | Using where |

+----+-------------+-------+------+------+-------------+

从查询执行计划可以看出,子查询已经被消除,变为了两表的嵌套循环连接,这说明MySQL对此类的子查询进行了优化。看到这里,我们可以感受到MySQL在子查询方面的强大了,是不是?



4 对比
我们把原始的SQL语句复制一份,目的是查阅方便。

S1:SELECT * FROM t3 WHERE b3 IN (SELECT a1 FROM t1);

S2:SELECT * FROM t3 WHERE b3 IN (SELECT id1 FROM t1);

S3:SELECT * FROM t3 WHERE id3 IN (SELECT a1 FROM t1);

S4: SELECT * FROM t3 WHERE b3 IN (SELECT b1 FROM t1 WHERE a1=a3);

然后对比如下:

SQL语句

语句特点

ToprowDB

PostgreSQL

MySQL

S1

非相关子查询,子查询目标列为普通列

没有被优化

Semi Join优化

Join优化

S2

非相关子查询,子查询目标列为键

没有被优化

Semi Join优化

Join优化

S3

非相关子查询,子查询目标列为主键列

没有被优化

Semi Join优化

Join优化

S4

相关子查询,子查询带有WHERE条件

Join优化

没有被优化

Join优化

分析:

q 从整体上看,对于IN类型的子查询,MySQL的优化能力强,ToprowDB差,PostgreSQL接近MySQL

q PostgreSQL不支持相关子查询的优化,而MySQL和ToprowDB都支持

5 结尾
总结一下,从前面的例子可以看出,MySQL全面胜出,ToprowDB和PostgreSQL各有所长。
————————————————
版权声明:本文为CSDN博主「那海蓝蓝」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fly2nn/article/details/61924787

相关文章