使用NHibernate在C#项目中使用一个相当典型的带参数的SQL插入查询;它可能是这样写的:
Session
.CreateSQLQuery(
@"INSERT INTO my_table(COL_A, COL_B, ...,
..., COL_M, COL_N)
VALUES (:VAL_A, :VAL_B, ....,
..., :VAL_M, :VAL_N)")
.SetParameter("VAL_A", "input for A")
.SetParameter("VAL_B", "input for B")
(...)
.SetParameter("VAL_N", "input for N")
.ExecuteUpdate();
这感觉组织得很好,对我来说很容易阅读,这是我喜欢的,但我对查询本身包含的空白感到好奇。我们可以通过写下面的一些变体来删除它,我在一些案例中看到了这一点。不过,这需要更多的精力来编写,并且可能会影响可读性:
Session
.CreateSQLQuery(
@"INSERT INTO my_table(COL_A, COL_B, ..., " +
@" COL_M, COL_N)" +
@" VALUES (:VAL_A, :VAL_B, ....," +
@" :VAL_M, :VAL_N)")
.SetParameter(...)
那么,我的问题是,这样做是否有意义?
我模糊地记得几年前听到过这件事;我们应该限制空白的数量,因为这可能会影响查询的性能。我的直觉是,这(如果有的话(的影响可以忽略不计,而且不值得付出代价,但获得更多的见解会很有趣。
- 像这样添加空白实际上会以任何方式影响性能吗?(除了网络延迟之外,我还认为在目前的大多数情况下,网络延迟可以忽略不计(
- 如果是这样,NHibernate中是否有任何优化可以处理/减少这种影响
- 结果可能取决于使用了哪个底层数据库系统?(在我目前的案例中,是一个Oracle数据库(
更改空白不会直接影响Oracle SQL性能,但它可以通过避免SQL性能特性来间接影响性能。但是,即使有一个奇怪的原因导致这个查询由于添加空间而受到影响,一般来说,您也不应该停止格式化SQL。
一些SQL优化功能,如SQL概要文件和大纲,是基于SQL语句文本的MD5散列的。对语句的任何更改,甚至添加或删除空格,都将生成不同的哈希。如果DBA或调优顾问任务创建了一个提高语句性能的SQL配置文件,那么在对查询进行任何微不足道的更改后,该配置文件将不再工作。
SQL重新优化时会出现相关问题。优化器从错误中吸取教训,并可以在语句第二次或第三次运行时更改执行计划。优化器很少会吸取错误的教训,SQL语句在第二次或第三次执行时会变慢。在这种情况下,添加或删除空间将使查询运行得更快——至少在最初是这样。
这些幕后优化是在不更改查询的情况下提高查询性能的强大工具。不幸的是,他们还倾向于制造货运狂热的编程神话;有些人做了一个微不足道的更改,性能提高了,他们认为自己偶然发现了一个神秘的性能秘密。这可能是整个";使用计数(1(代替计数(*(";胡说八道开始了。
继续使用正确格式化查询所需的所有空白。如果你遇到了一个真实的、可衡量的问题,请比较执行计划,看看发生了什么变化以及原因。如果同事坚持将删除空白作为一条一般规则,请他们提供一个可重复的测试用例来证明他们的主张。
否。SQL语句实际上是";编译的";在它们运行之前,空白对结果没有明显的影响,除非缺少空白会导致语法错误