0

SQL 是如何实际运行的?

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

4

1 回答 1

5

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

对于像这样row_id = 123的选择,实际的查询计划取决于您是否有索引。如果不这样做,将使用表扫描逐行检查表。但是,如果您确实有一个索引 on row_id,则有机会通过使用该索引来跳过大部分行。在这种情况下,数据库不会逐行搜索。

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

EXPLAIN SELECT * FROM table WHERE row_id = 123;

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

对于示例表,

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

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)

这意味着数据库将对整个表进行顺序扫描并找到带有row_id = 123.

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

CREATE INDEX test_idx ON test(row_id);

那么同样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)

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

有关查询优化的详细信息,请参阅《数据库系统:全书》中的第 15 章和第 16 章。

于 2013-05-12T17:29:19.930 回答