绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
ToprowDB Dynamic Server 查询优化技术---子查询优化--01-2
2022-03-30 14:38:16

在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

分享好友

分享这个小栈给你的朋友们,一起进步吧。

ToprowDB
创建时间:2022-03-30 14:20:33
华胜信泰ToprowDB数据库软件产品(以下简称:ToprowDB)是基于国际领先的云计算、大数据理念与技术,自主设计并研发的“自主可控、安全可信、高效可用”的高性能数据库软件产品。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 飘絮絮絮丶
    专家
戳我,来吐槽~