假设我在 MySQL(或 PostgreSQL)中执行一个查询,比方说:
SELECT * FROM USER WHERE age = 20;
数据库引擎是否在我每次执行时解析和编译查询/语句?或者它是否保存了以前的语句/查询的一些缓存?
如果它有缓存机制,它会区别对待下面两个查询吗?
/* first query */
SELECT * FROM USER WHERE age = 20 AND name = 'foo';
/* second query */
SELECT * FROM USER WHERE name = 'foo' AND age = 20;
我这样问是因为我在我的代码中使用了一些工具来生成 SQL 查询,这与查询中条件的顺序不一致。我只是想确保此行为不会影响我的数据库性能。
谢谢
最佳答案
SQL 是一种声明性 语言,而不是过程性 语言。实际执行的基本上是一个 DAG(有向无环图)组件,您可能不会将其识别为 SQL 结构(例如“散列连接”或“过滤器”或“排序”)。
您在 name
和 age
条件下提到的两个查询将编译为基本相同的编译形式。如果您有适当的索引或分区,两个查询都会使用它们。如果您不这样做,那么他们可能以不同的顺序执行 bool 条件。然而,这种查询的大开销是全表扫描,而不是单独的比较。
在极少数情况下,您可能希望确保条件按特定顺序执行——尤其是当您有昂贵的用户定义函数时。编译器通常会为你做这件事。如果不是,您可以使用 case
表达式:
where (case when col <> 0 then 0
when expensive_function( . . . ) then 1
else 0
end) = 1
这将仅在 col = 0
时执行昂贵的函数,因为 case
表达式按顺序计算它们的表达式(在非聚合查询中)。
至于缓存,这取决于服务器和选项。通常,数据库会缓存查询计划,因此不需要重新编译。这通常是在准备好的语句级别而不是查询文本。数据库通常不会缓存结果,因为基础表中的数据可能会更改。
关于mysql - MySQL/PostgreSQL 是否缓存查询的解析/编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50307198/