SQL如何实际运行?
例如,如果我想找到一个row_id=123
的行,SQL会从内存顶部逐行查询吗?
答案 0 :(得分:5)
这是query optimization的主题。简而言之,根据您的查询,数据库系统首先尝试生成并优化可能具有最佳性能的query plan,然后执行该计划。
对于row_id = 123
这样的选择,实际的查询计划取决于您是否有index。如果不这样做,将使用表扫描逐行检查表。但是如果你在row_id
上有索引,则有可能通过使用索引跳过大多数行。在这种情况下,DB不会逐行搜索。
如果你正在运行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 ms 和 0.171 ms 。
有关查询优化的详细信息,请参阅Database Systems: The Complete Book中的第15章和第16章。