文章目录
- 1.使用EXPLAIN分析查询计划
- 1.1 Seq Scan:全表顺序扫描, 表示数据库将按顺序扫描整个表,适用于小表或无索引的情况。
- 1.2 Index Scan: 基于索引扫描,但不只是返回索引列的值。
- 1.3 IndexOnly Scan:基于索引扫描,但只返回索引列的值,简称为覆盖索引。
- 1.4 Bitmap Heap Scan: 基于索引的扫描,使用位图索引进行扫描。
- 2.分析查询计划总结
- 3.创建索引优化查询
- 3.1 创建索引
- 3.2 创建覆盖索引(又称 INCLUDE 索引)
- 3.3 创建复合索引
在数据库应用查询中,尤其是在大数据级(百万级)sql数据查询中,查询优化非常重要。
一、可以节省数据库服务器开销,防止数据库服务器并发导致的宕机;
二、提高用户体验,在百万级数据中可能会引发查询效率慢,需要加载老半天才能返回数据,影响用户体验;
1.使用EXPLAIN分析查询计划
-- 示例:使用EXPLAIN分析SELECT查询计划
EXPLAIN SELECT * FROM your_table WHERE your_condition;
EXPLAIN输出的执行计划包括以下关键信息:
- 类型:Seq Scan(顺序扫描)、Index Scan(索引扫描)等。
- Filter: 描述在执行计划中应用的过滤条件。
- Rows Removed by Filter:表明过滤操作过滤了多少行记录。
- Planning time: 表明生成查询计划的时间。
- Execution time:表明了实际的sql执行时间,其中不包括查询计划的生成时间。
在执行计划中,不同的计划节点代表不同的执行操作。以下是常见的执行计划节点:
1.1 Seq Scan:全表顺序扫描, 表示数据库将按顺序扫描整个表,适用于小表或无索引的情况。
(1)分析查询sql示例:
EXPLAIN SELECT * FROM "202312_copy1" where name = 'a'
(2)分析结果:
一般查询没有创建索引的表需要全表顺序扫描,explain会输出以下:
(cost=0.00…608.00 rows=2991 width=221)表明了这个节点的代价估计。
1.2 Index Scan: 基于索引扫描,但不只是返回索引列的值。
主要用来在where条件中存在的索引列时的扫描。
(1)分析查询sql示例:
EXPLAIN SELECT * FROM "test" where name = 'b'
(2)分析结果:
1.3 IndexOnly Scan:基于索引扫描,但只返回索引列的值,简称为覆盖索引。
(1)分析查询sql示例:
EXPLAIN SELECT name FROM "test" where name = 'b'
(2)分析结果:
1.4 Bitmap Heap Scan: 基于索引的扫描,使用位图索引进行扫描。
BitmapHeap Scan,把BitmapIndex Scan 返回的Bitmap 结构转换为元组结构;
BitmapIndex Scan和Index Scan很相似,都是基于索引的扫描,但是BitmapIndex Scan节点每次执行返回的是一个位图而不是一个元组,其中位图中每一个代表扫描到的一个数据块。而BitmapHeap Scan一般会作为BitmapIndex Scan的父节点,将BitmapIndex Scan 返回的Bitmap 结构转换为元组结构。
这样做最大的好处就是把Index Scan的随机读转换成了按照数据块的物理顺序读取,在数据量比较大的时候,这会大大提升扫描的性能。
(1)分析查询sql示例:
EXPLAIN SELECT * FROM "test" where name = 'a'
(2)分析结果:
2.分析查询计划总结
-一般来说,index scan 要比sep scan快,但是如果获取的结果集占所有结果的比重很大时,这是index scan因为要先扫描索引,再读表数据,反而不如全表扫描来的快。如果获取的结果集占比比较小,但元组数很多时,可能 Bitmap Index Scan的性能要比index scan好。如果获取的结果集能够被索引覆盖,则index only scan因为不用去读取数据表,只去读取索引,所以一般性能最好,但是如果VM文件还未生成,可能性能就会比index scan 差些。
3.创建索引优化查询
3.1 创建索引
根据查询条件创建对应的索引,提高检索速度。
-- 示例:创建索引
CREATE INDEX idx_your_column ON your_table(your_column);
3.2 创建覆盖索引(又称 INCLUDE 索引)
在索引中包含所有查询需要的字段,避免对表的实际数据进行访问。
-- 示例:创建覆盖索引
CREATE INDEX idx_your_covering_index ON your_table(your_column) INCLUDE(your_other_column);
3.3 创建复合索引
对于涉及多个列的查询,使用复合索引可以提高性能。确保复合索引的列顺序与查询的条件一致。
复合索引是在多个列上创建的索引,用于优化涉及这些列的查询。复合索引的顺序很重要,最左匹配原则决定了它的有效性。
-- 示例:创建复合索引
CREATE INDEX idx_your_compound_index ON your_table(column1, column2);