假设我在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查询,这与查询中条件的顺序不一致。我只想确保这种行为不会影响我的数据库性能。
谢谢
1条答案
按热度按时间gcmastyq1#
sql是一种声明性语言,而不是过程性语言。实际执行的基本上是一个dag(有向无环图),它是一些您可能无法识别为sql构造的组件(例如“hash join”或“filter”或“sort”)。
你提到的这两个问题的条件是
name
以及age
将编译成基本相同的编译形式。如果您有适当的索引或分区,两个查询都将使用它们。如果不这样做,那么它们可能会以不同的顺序执行布尔条件。然而,这种查询的最大开销是全表扫描,而不是单个比较。在一些罕见的情况下,您可能需要确保条件是按特定顺序执行的——特别是如果您有一个昂贵的用户定义函数。编译器通常会为您执行此操作。如果没有,你可以使用
case
表达式:只有当
col = 0
,因为case
表达式按顺序计算其表达式(在非聚合查询中)。至于缓存,这取决于服务器和选项。一般来说,数据库缓存查询计划,因此它们不需要重新编译。这通常是在准备好的语句级别,而不是查询的文本。数据库通常不会缓存结果,因为基础表中的数据可能会更改。