关键字:
顺序扫描、索引扫描、KingbaseES、人大金仓、KingbaseES
概述
关系型数据库都需要产生一个最佳的执行计划从而在查询时耗费的时间和资源最少。查询优化器是提升查询效率非常重要的一个手段,并且查询优化器的优化过程对数据库开发人员是透明的。查询优化器的主要作用就是生成最优的执行计划。对于一条给定的SQL查询语句,通常会有一个或多个执行计划可供选择,每个执行计划都可以返回正确的结果,优化器就会选择预期运行最快的执行计划。
我们在对数据表中的数据进行任何操作之前,都需要先获取数据表中的数据,在KingbaseES中,常见的单表扫描方式包括:
- 顺序扫描
- 索引扫描
顺序扫描
-
- 概念
顾名思义,顺序扫描就是按照顺序扫描数据表中所有页的item指针。如果一个表有100页,每一页有1000条记录,顺序扫描就会累计获取100*1000条记录并检查是否匹配隔离级别以及where条件。因此,即使只有1条几记录满足条件,也会扫描100*1000条记录。
-
- 顺序扫描的适用情况
·高选择率:在选择率高到一定程度的时候,相比于顺序扫描,索引扫描的代价会更高,所以这种情况下更适合索引扫描;
- 创建表test_aa:
create table test_aa (p_no int PRIMARY KEY,p_price numeric,p_name text);
- 对表test_aa的p_price创建索引:
create index p_price_idx1 on test_aa(p_price);
- 对表test_aa构造50万条随机数据:
Insert into test_aa values
(generate_series(1,500000),random()*10::NUMBER(5,2),md5(random()::text));
- 对大批量数据进行查询,查看其扫描方式:
此时,分析显示该表是通过顺序扫描进行查询数据。
5)通过禁用seqscan让优化器使用indexscan:
set enable_seqscan to off;
可以看出,此时使用索引扫描的计划时间和执行时间均比顺序扫描的计划时间和执行时间更高,因此,在进行高选择率查询时,数据库会优先使用顺序扫描执行查询。
索引扫描
-
- 概念
与顺序扫描不同,索引扫描并不是顺序地获取所有记录。相反,它使用与查询中涉及的索引相对应的不同数据结构(取决索引的类型),并通过非常小的扫描定位所需的数据(根据谓词)子句。然后,使用索引扫描找到的条目直接指向表中的数据,然后根据隔离级别提取该条目来检查可见性。
索引扫描有两个步骤:
1)从索引相关的数据结构中获取数据。它返回表中相应数据的TID;
2)直接访问相应的表页以获得整个数据。
-
- 索引扫描的适用情况
·索引扫描的基本算法为:根据条件值,通过索引结构快速的找到条件值的索引位置,进而找出所有符合条件的值。
·选择率低:在选择率低的情况下,索引扫描需要扫描的索引页面和数据页面要下于顺序扫描,由此付出的IO和CPU代价要小于顺序扫描,所以优化器会选择索引扫描;
1)对上述表test_aa进行低选择率查询:
可以发现此时是使用索引扫描进行数据的查询。
- 通过禁用indexscan和bitmapscan让优化器选择seq_scan:
- 再次执行查询语句:
- 可以发现,此时索引扫描的计划时间和执行时间明显更少。
参考资料
《KingbaseES产品手册》—查询优化器简介