首页 > 其他分享 >KingbaseES 为什么select主键列不走索引

KingbaseES 为什么select主键列不走索引

时间:2024-04-03 17:15:45浏览次数:22  
标签:rows hit .. 列不走 扫描 cost shared KingbaseES 主键

背景

有客户提出一个问题。 一个类似这样的SQL语句,select count(id) from 为什么执行计划用全表扫,不用索引。id列上有主键。

分析

test=# explain (analyze, buffers ) select count(id) from t1;
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=3385.00..3385.01 rows=1 width=8) (actual time=33.969..33.970 rows=1 loops=1)
   Buffers: shared hit=885
   ->  Seq Scan on t1  (cost=0.00..2885.00 rows=200000 width=4) (actual time=0.025..16.867 rows=200000 loops=1)
         Buffers: shared hit=885
 Planning Time: 0.044 ms
 Execution Time: 33.992 ms
(6 rows)

如下,临时关闭全表扫描,执行计划用到了索引,而且用到了并行任务,执行计划时间77毫秒,显然并行索引扫描的cost的估算完成成本4937.75明显要高于全表扫描完成成本的2885。

test=# set enable_seqscan =off;
SET
test=# explain (analyze, buffers ) select count(id) from t1;
                                                                       QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------
--------------------------
 Finalize Aggregate  (cost=6146.30..6146.31 rows=1 width=8) (actual time=77.077..77.164 rows=1 loops=1)
   Buffers: shared hit=891 read=551
   ->  Gather  (cost=6146.09..6146.30 rows=2 width=8) (actual time=76.250..77.157 rows=3 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         Buffers: shared hit=891 read=551
         ->  Partial Aggregate  (cost=5146.09..5146.10 rows=1 width=8) (actual time=65.968..65.969 rows=1 loops=3)
               Buffers: shared hit=891 read=551
               ->  Parallel Index Only Scan using id_pkey on t1  (cost=0.42..4937.75 rows=83333 width=4) (actual time=9.001..5
3.003 rows=66667 loops=3)
                     Heap Fetches: 200000
                     Buffers: shared hit=891 read=551
 Planning Time: 0.073 ms
 Execution Time: 77.191 ms
(13 rows)

如下,关闭并行任务后重试,执行计划用到了index only scan,它的意思是不需要回表的索引扫描,结果集所需要的数据从索引中就可以获取,因为 select id 列上有主键。关闭并行后,这次执行计划对比第一个全表扫描的执行计划步骤极其相似,区别在于seq scan 和 index only scan。我们可以看到执行时间一个是33毫秒,一个是50毫秒。为什么执行时间上有此差别?

test=# set max_parallel_workers_per_gather=0;
SET
test=#
test=# explain (analyze, buffers ) select count(id) from t1;
                                                             QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------
-------
 Aggregate  (cost=6604.42..6604.43 rows=1 width=8) (actual time=50.032..50.033 rows=1 loops=1)
   Buffers: shared hit=1437
   ->  Index Only Scan using id_pkey on t1  (cost=0.42..6104.42 rows=200000 width=4) (actual time=0.018..34.042 rows=200000 lo
ops=1)
         Heap Fetches: 200000
         Buffers: shared hit=1437
 Planning Time: 0.059 ms
 Execution Time: 50.059 ms
(7 rows)

如下,执行vacuum t1后, heap fetches由200000变成了0,执行时间从50毫秒变成了35毫秒。heap fetches 代表需要扫描的数据块个数。虽然Index Only Scan 可以从索引直接输出结果,但是因为MVCC机制,需要对扫描的元组进行可见性判断,即检查visibility MAP 文件。当新建表之后,如果没有进行过vacuum或autovacuum操作,这时还没有VM文件,而索引没有保存记录的版本信息,索引Index Only Scan 还是需要扫描数据块来获取版本信息。

此时的执行计划和第一次执行计划的全表扫描时间更接近了,区别是全表扫描的执行时间是33毫秒,index only scan的执行时间是35毫秒。我们分析一下,全表扫描执行计划中,buffers:shared hit=885,index only scan执行计划中buffers:shared hit=553。shared hit表示从缓存中命中的page数,既然全表扫描执行计划缓存中命中数高于index only scan,为什么执行计划时间更短呢?因为涉及数据的扫描方式,索引扫描涉及随机IO,而顺序扫描也就是全表扫描涉及顺序IO。大多数情况下,Index Scan 要比 Seq Scan 快。但是如果获取的结果集占所有数据的比重很大时,这时优化器计算成本后可能不会选择使用index Scan,只有当计算得出顺序IO的代价大于随机IO时,才会选择索引扫描。本案例中,返回全表结果集数据,优化器计算随机IO的获取成本无疑高于顺序IO,是否使用索引扫描和需要扫描的数据量,列的唯一值占总行数比值有关。

test=# vacuum t1;
VACUUM
test=#
test=# explain (analyze, buffers ) select count(id) from t1;
                                                             QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------
-------
 Aggregate  (cost=5716.42..5716.43 rows=1 width=8) (actual time=35.790..35.791 rows=1 loops=1)
   Buffers: shared hit=553
   ->  Index Only Scan using id_pkey on t1  (cost=0.42..5216.42 rows=200000 width=4) (actual time=0.014..20.739 rows=200000 lo
ops=1)
         Heap Fetches: 0
         Buffers: shared hit=553
 Planning Time: 0.086 ms
 Execution Time: 35.815 ms
(7 rows)

标签:rows,hit,..,列不走,扫描,cost,shared,KingbaseES,主键
From: https://www.cnblogs.com/kingbase/p/17921588.html

相关文章

  • KingbaseES V8R6集群运维案例之---同城双中心switchover案例
    KingbaseESV8R6集群运维案例之---同城双中心switchover案例案例说明:在同城双中心执行switchover在线切换后,双中心架构保持不变。适用版本:KingbaseESV8R6集群架构:一、切换前集群节点状态如下所示,切换前集群的主库(Primary)位于同城灾备中心,现在执行switchover在线切......
  • KingbaseES删除重复数据的方法
    前言Oracle数据库去除重复数据方法一般根据rowid进行去重,KingbaseES数据库如何去重呢?可以根据ctid去重。我们使用大数据量测试,因为一般生产环境数据量还是蛮大的。测试创建一张测试表,并插入一定量的重复数据,数据量21万,其中重复数据1万。createtabledel(idint,namevarcha......
  • KingbaseESV8R6等待事件之LWLockBuffer_IO
    说明当并发会话尝试访问同一页面时,等待其他进程完成其输入/输出(I/O)操作时,就会发生LWLock:BufferIO事件。其目的是将同一页读取到共享缓冲区中。等待事件发生过程每个sharedbuffer都有一个与LWLock:BufferIO等待事件关联的I/O锁,每次都必须在共享缓冲池外检索块。此锁用于处理......
  • 如何查看KingbaseES数据库占用操作系统内存情况
    当遇到数据库内存告警,并且操作系统内存使用不足,需要分析内存占用的方法。KingbaseES数据库使用操作系统缓存机制,大量的内存很可能被BUFFER/CACHE占用了。从free命令可以看到总共有2.5G多内存,使用了291MB,free剩下1.7GB多,BUFF/CACHE占了474MB。available有1.3GB多,当前这台数据库服......
  • KingbaseES数据库权限简写说明
    前言为了方便,我们测试环境经常使用system用户执行测试,它拥有最高权限。角色基本上是用户和组的概念。你可以以角色身份登录,并且一个角色可以属于另一个角色。每个角色都有一个类似的属性,指示你是否可以作为该角色登录,以及该角色是否从所属角色继承权限。你可以使用命令将角色添......
  • KingbaseES复制冲突中谁阻塞walreplay
    背景回顾一下流复制冲突相关参数:hot_standby_feedback:从库反馈给主库快照,主库vacuum时不回收最老快照之后产生的垃圾,注:备库长查询将导致主库表膨胀。vacuum_defer_cleanup_age:当触发vacuum时,延迟指定事务后触发。recovery_min_apply_delay:如果将此参数设置为5分钟,则只......
  • KingbaseES 数据库创建索引慢的可能原因
    1.表大小如果表太大,数据很多,索引创建的时候,会导致创建索引的时间很慢。如果表很大,可以考虑重新设计表结构或拆分表。还可以考虑使用分区表,使子分区的数据减少,创建分区表也可以使索引变小,增加索引创建速度,有助于查询效率。2.索引类型不同类型的索引建立的速度可能会有所不同,因......
  • KingbaseES 数据库IO优化方向总结
    前言数据库中的IO性能是优化中的重中之重,根据木桶原理,解决了IO这个最容易引起业务堵塞的问题,就能解决绝大部分性能问题。下面从几个方面总结一下I/O优化问题。第一,使用相对速度快的高性能存储设备。一般会考虑使用固态硬盘(SSD)或RAID阵列以获得更快的读写速度。高性能低......
  • KingbaseES数据库运维案例---SCOTT用户及对象创建
    案例说明:生产用户从Oracle环境迁移到KingbaseES数据库后,需要使用Oracle下scott用户的应用测试环境,本案例借助Oracle创建scott用户应用环境的脚本,创建KingbaseES下的应用测试环境。适用版本:KingbaseESV8R3/R6SCOTT用户有四张数据表:1)部门信息表:dept2)雇员信息表:emp3)工资等......
  • KingbaseES V8R6集群运维案例之---single-pro模式备份
    案例说明:KingbaseESV8R6集群物理备份配置参数_target_db_style,可选single或cluster或single-pro。single对应单机模式的目标数据库实例,cluster对应集群模式的目标数据库实例,single-pro对应集群模式的每个DB节点独立备份。本案例详细描述集群架构在singl-pro模式下的备份。适用......