mysql - MySQL/PostgreSQL 是否缓存查询的解析/编译?

标签 mysql sql database postgresql

假设我在 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 结构(例如“散列连接”或“过滤器”或“排序”)。

您在 nameage 条件下提到的两个查询将编译为基本相同的编译形式。如果您有适当的索引或分区,两个查询都会使用它们。如果您不这样做,那么他们可能以不同的顺序执行 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/

相关文章:

mysql - 如何在SQL中执行动态if语句?

mysql - Rails 中迁移数据库但未找到表?

MySQL 在连接时丢失行

php - 如何自动增加mysql id

mysql - 如何从初始行创建多行

mySQL SELECT 使用 LEFT JOIN,返回值或 NULL WHERE 列在右表中指定

mysql - 如何解决 "#2006 - MySQL server has gone away"和 "ERROR 2013 (HY000): Lost connection to MySQL server during query"

java - 我看不到添加到我的 ListView 的第一项

mysql - 数据库设计 - 许多带有唯一标签的表还是一张带有所有标签的表?

sql - 如何在H2中将时间转换为24小时格式