where 子句中的参数化查询

在传值的时候使用动态参数 @param 的方式有以下两个好处:

  1. 防止 SQL 注入的最佳方式
  2. 提高查询性能

像 SQL Server 和 Oracle 这样具有执行计划缓存的数据库,在多次执行同一语句时可以重复使用执行计划。这节省了重建执行计划的工作,但只有在 SQL 语句完全相同的情况下才能发挥作用。如果在 SQL 语句中放入不同的值,数据库会像处理不同的语句一样处理它,并重新创建执行计划。当使用动态参数时,SQL 语句就不会发生变化。

当然也有例外情况。例如,当某个字段的数据量分布不均时。

以 EMPLOYEES 表为例,假如 subsidiary_id = 20 的数据占比很少,而 subsidiary_id = 30 占比很高。对于前者应该使用索引,而后者应该使用全表扫描效率更高。优化器使用 SUBSIDIARY_ID 的直方图来确定数据的频率,并为这两个查询创建不同的执行计划。

当使用动态参数时,因为动态参数对优化器来说是不可见的,优化器没有可用的具体数值来确定其频率。它只是假设一个平等的分布,并且总是得到相同的行数估计和成本值。因此它将总是选择相同的执行计划。

参数嗅探 (parameter sniffing) 也是由类似的原因造成的。

作者

Jesse

发布于

2021-06-02

更新于

2021-07-19

许可协议

评论