oracle中SQL的缓存
Posted
技术标签:
【中文标题】oracle中SQL的缓存【英文标题】:CACHE of SQL in oracle 【发布时间】:2009-11-29 16:42:17 【问题描述】:oracle如何缓存一个查询(SQL),查询执行包含以下步骤。 1.解析 2. 执行 3. 获取
在第一步中oracle检查查询是否存在于CACHE(共享池)中(如果查询相同并且基于LRU,它将存在),如果存在则将跳过PARSING并开始执行。 因此,为了提高查询性能,我们必须使用绑定变量并使用相同的 sql 查询。
但是在解析oracle也验证身份验证(用户访问),如果多个用户正在使用相同的查询,oracle如何跳过/使用解析?
【问题讨论】:
【参考方案1】:查询的解析与用户无关,它取决于查询。请注意,字符匹配需要精确的字符。查询中的空白和 cmets 将导致它错过共享池匹配。
解析树然后用于生成执行计划。如果在新查询中使用与匹配查询相同的架构,则使用现有的执行计划。
您可以通过创建多个架构来测试这一点,一个包含少量数据,一个包含大量数据 数量。然后分析所有表。看看数据量大不相同的同一查询的执行计划。这将显示同一查询的不同执行计划。
现在大量运行查询并检查第一次所花费的时间 然后是随后的处决。使用 Oracle Trace 并查看“Re-Parse”的左手疼痛 频率。这也可以从一些字典表中收集到。
看看The Oracle documentation on using Oracle Trace
【讨论】:
如果您需要更多详细信息或想要更具体,请在 cmets 中询问。我会尽力帮助你的。 查询绑定到解析模式名称和会话用户。因此 user_a 可以执行 ALTER SESSION SET CURRENT_SCHEMA=USER_B 并运行 SELECT * FROM EXAMPLE。该查询在 USER_B 中查找EXAMPLE 的表/视图/同义词,但还会检查 USER_A 是否对这些对象具有权限。可以有多个具有相同文本的 SQL 引用不同模式中具有相同名称的对象。 @Gary:公共同义词跨模式【参考方案2】:第一步oracle检查查询是否存在于CACHE(共享池)中(如果查询相同并且基于LRU,它将存在),如果存在则将跳过PARSING并开始执行。因此,为了提高查询性能,我们必须使用绑定变量并使用相同的 sql 查询。
这是您在 Oracle 上执行查询时的实际过程:
-
解析步骤
-
语法检查
语义分析
查询是否已在其他会话中执行?
-
解析
优化
为查询生成计划。
如果 #1.3 的答案是肯定的 - Oracle 会跳过硬解析部分,并使用现有的查询计划。
更多信息: * AskTom: Difference between soft parse and hard parse * Bind variables - The key to application performance
【讨论】:
【参考方案3】:Oracle 中的通常做法是创建具有定义者权限的存储过程,这意味着无论谁调用它们,查询都以其定义者的权限执行。这就是缓存运作良好的原因。
如果您创建具有调用者权限 (authid current_user
) 的过程或包,则将为每个调用者分别解析查询。
详情请见Invoker Rights Versus Definer Rights。
【讨论】:
这不是关于过程/函数/包内部的查询,它是简单的选择语句 简单的选择语句等于调用者权限的情况。当两个不同的用户发出相同的查询时,该查询将被解析两次。您可以在 V$SQL 中为该查询找到两行,具有相同的 sql_text 和 sql_id,但不同的 parsing_schema_name。 我错了。如果两个查询在语法和语义上相等(即都使用相同的表),则查询将仅被硬解析一次。以上是关于oracle中SQL的缓存的主要内容,如果未能解决你的问题,请参考以下文章
Oracle删除一条SQL在Shared Pool里缓存的执行计划的三种方法
oracle数据库中有数据,通过pl/sql查询不到,用sqlplus能查到,PL/SQL developer会对数据进行本地缓存