SQL实际上如何在内存中运行?逐行

Gav*_*eng 0 sql sql-execution-plan

SQL如何实际运行?

例如,如果我想查找一行row_id=123,SQL查询会从内存顶部逐行搜索吗?

Yan*_*ang 5

这是查询优化的主题.简而言之,根据您的查询,数据库系统首先尝试生成并优化可能具有最佳性能的查询计划,然后执行该计划.

对于选择row_id = 123,实际查询计划取决于您是否有索引.如果不这样做,将使用表扫描逐行检查表.但是如果你确实有索引row_id,则有可能通过使用索引跳过大多数行.在这种情况下,DB将不会逐行搜索.

如果你正在运行PostgreSQL或MySQL,你可以使用

EXPLAIN SELECT * FROM table WHERE row_id = 123;
Run Code Online (Sandbox Code Playgroud)

查看系统生成的查询计划.

对于示例表,

CREATE TABLE test(row_id INT);          -- without index
COPY test FROM '/home/user/test.csv';   -- 40,000 rows
Run Code Online (Sandbox Code Playgroud)

EXPLAIN SELECT * FROM test WHERE row_id = 123输出:

                  QUERY PLAN                      
------------------------------------------------------
 Seq Scan on test  (cost=0.00..677.00 rows=5 width=4)
    Filter: (row_id = 123)
 (2 rows)
Run Code Online (Sandbox Code Playgroud)

这意味着数据库将对整个表执行顺序扫描并查找行row_id = 123.

但是,如果在列上创建索引row_id = 123:

CREATE INDEX test_idx ON test(row_id);
Run Code Online (Sandbox Code Playgroud)

然后同样EXPLAIN会告诉我们数据库将使用索引扫描来避免遍历整个表:

                            QUERY PLAN                                
--------------------------------------------------------------------------
 Index Only Scan using test_idx on test  (cost=0.00..8.34 rows=5 width=4)
   Index Cond: (row_id = 123)
 (2 rows)
Run Code Online (Sandbox Code Playgroud)

您还可以使用它EXPLAIN ANALYZE来查看SQL查询的实际性能.在我的机器上,顺序扫描和索引扫描的总运行时间分别为14.738 ms0.171 ms.

有关查询优化的详细信息,请参阅" 数据库系统:完整手册"中的第15章和第16章.