MST

星途 面试题库

面试题:PostgreSQL执行计划中常见的节点类型及作用

请阐述在PostgreSQL执行计划里,Seq Scan(顺序扫描)、Index Scan(索引扫描)和Nested Loop(嵌套循环)这几种常见节点类型的作用分别是什么,在什么样的查询场景下会各自被使用?
10.3万 热度难度
数据库PostgreSQL

知识考点

AI 面试

面试题答案

一键面试

Seq Scan(顺序扫描)

  • 作用:顺序扫描会对表中的每一行数据依次进行读取,从表的开头遍历到结尾,不依赖索引。它读取整个表的数据页,然后对每一行数据进行过滤,判断是否满足查询条件。
  • 适用场景
    • 当表非常小,全表扫描的成本低于使用索引时。例如只有几十行数据的表,使用索引可能带来额外的索引查找开销,不如直接全表扫描。
    • 查询条件没有合适的索引支持,例如在一个没有索引的列上进行过滤查询。如 SELECT * FROM users WHERE random_column = 'value';,这里 random_column 没有索引,就可能触发顺序扫描。
    • 大部分数据都满足查询条件,全表扫描的效率可能比通过索引多次定位数据更高。例如查询 SELECT * FROM orders WHERE order_date > '2023 - 01 - 01';,如果大部分订单日期都在这个时间之后,顺序扫描可能更优。

Index Scan(索引扫描)

  • 作用:索引扫描利用索引结构来快速定位满足查询条件的数据行。索引是一种数据结构,它提供了一种快速查找数据的方式。通过索引,数据库可以快速定位到满足条件的索引项,然后通过索引项找到对应的数据行。
  • 适用场景
    • 当查询条件在有索引的列上,并且索引的选择性较好(即索引列的值分布比较均匀,能有效减少扫描的数据量)。例如 SELECT * FROM products WHERE product_id = 123;,如果 product_id 列上有索引,就很可能触发索引扫描快速定位到对应产品。
    • 范围查询时,如果索引是有序的,索引扫描可以快速定位到满足范围条件的起始位置,并按顺序读取满足条件的数据。如 SELECT * FROM employees WHERE salary > 50000;,若 salary 列有索引,可利用索引快速定位符合条件的数据。
    • 当查询的列包含在索引中(覆盖索引),数据库可以直接从索引中获取所需数据,而无需回表操作(即从索引找到数据行对应的物理位置再去读取完整数据行),这样能大大提高查询效率。例如 SELECT product_name FROM products WHERE product_id = 123;,如果 product_idproduct_name 都在同一个索引中,就可以直接从索引获取数据。

Nested Loop(嵌套循环)

  • 作用:嵌套循环是一种连接(Join)操作的执行方式。它将两个表(内表和外表)进行连接,对外表的每一行数据,都在内表中进行匹配查找满足连接条件的行。具体过程是外层循环遍历外表的每一行,对于每一行,内层循环在内表中进行全表扫描或索引扫描(取决于内表是否有合适索引及其他因素)来寻找匹配的行,然后将匹配的行组合作为结果输出。
  • 适用场景
    • 当外表数据量较小,内表有合适的索引时,嵌套循环连接效率较高。因为外层循环次数少,每次对内表进行索引扫描能快速找到匹配行。例如一个小的 departments 表和一个大的 employees 表通过 department_id 连接,departments 表数据量小作为外表,employeesdepartment_id 列有索引,此时嵌套循环连接可能是较好选择。
    • 当连接条件比较复杂,其他连接方式(如哈希连接、合并连接)难以有效利用时,嵌套循环连接可能会被选择。因为嵌套循环连接可以灵活地处理各种连接条件,即使条件涉及多个列的复杂运算。