根据我们的经验(由很多业界专家证明),在 SQL Server 上取得的性能提高有 80% 来自对 SQL 编码的改进,而不是来自于对于配置或系统性能的调整。”
—凯文 克莱恩等,Transact-SQL Programming 作者
“经验表明 80%-90% 的性能调优是在应用级做的,而不是在数据库级”
—托马斯 白特,Expert One on One: Oracle 作者
可见sql语句对于数据库性能的重要性。
各种操作符的效率排序:(由高到低)
=
>
>=
<
<=
LIKE
<>
LIKE 和 <>都会导致全表搜索。效率最低。
各种操作符的效率排序:(由高到低)
仅有常量字符 (例如 where 1=1 )
仅有列名
仅有参数
多操作数表达式
精确数值类型
其他数值类型
日期类型
字符类型
NULL
由此可见最有效率的条件查询查询是 smallInt_column = 1;
1
WHERE column1 < column2 AND column2 = column3 AND column1 = 5
2
... WHERE 5 < column2 AND column2 = column3 AND column1 = 5
很显然表达式2和表达式1是同样的功能但是效率会高
不过经过研究证明 将常量放在表达式的右边效率要比放在左边高 例如 column > 5 就比 5 > column 效率高。
针对操作符的调优
比如我们有两个条件 用and连接 但是如果把概率大条件放在前面的话就会导致第二个and条件被执行的概率大好多,这样就可能会导致会做多次无用的查询,所以相对于and条件,应该把概率小条件的放在前面执行。(ps: oracle数据库是从由到左读搜索条件的),而对于or条件,应该把概率大的条件放在最前面,这样就第二个条件就会更少次数的执行。
尽量减少AND和OR的出现次数,多用一个连接条件就等于可能多做一次查询,优先用AND,OR条件可能将会导致全表搜索。
<> LIKE NOT 等操作符如果可以被别的操作符代替的话最好就不要用。因为用他们进行查询的时候不会用索引,而且可能导致全部查询。
例如:where column <> 3 可以 被 Where colunm >3 OR colunm < 3;
比较复杂的情况,根据集合的摩根定理:
IN 比 多个OR要快。
当 IN 操作符,是一系列密集的整型数字时,最好是查找哪些值不符合条件,而不是查找哪些值符合条件,因此,如下的查询条件就应该进行如下的转换:
UNION 用来合并两个结果集但是或过滤重复的值,UNION ALL则不会过滤重复的值。
查询 1:
SELECT * FROM Table1 WHERE column1 = 5 UNION SELECT * FROM Table1 WHERE column2 = 5 |
查询 2:
SELECT DISTINCT * FROM Table1 WHERE column1 = 5 OR column2 = 5 |
在上面的例子中,column1 和 column2 都没有索引。如果查询 2 总是比查询 1 执行的快的话,那么就可以建议总是将查询 1 转换成查询 2,但是有一种情况,这样做在一些数据库系统中可能会带来性能变差,这是由于两个优化缺陷所造成的。
第一个优化缺陷就是很多优化器只优化一个 SELECT 语句中一个 WHERE 语句,所以查询 1 的两个 SELECT 语句都被执行。首先优化器根据查询条件 column1 = 5 为真来查找所有符合条件的所有行,然后据查询条件 column2 = 5 为真来查找所有符合条件的所有行,即两次表扫描,因此,如果 column1 = 5 没有索引的话,查询 1 将需要 2 倍于查询 2 所需的时间。如果 column1 = 5 有索引的话,仍然需要二次扫描,但是只有在某些数据库系统存在一个不常见的优化缺陷却将第一个优化缺陷给弥补了。当一些优化器发现查询中存在 OR 操作符时,就不使用索引查询,所以在这种情况下,并且只有在这种情况下,UNION 才比 OR 性能更高。这种情况很少见,所以仍然建议大家当待查询的列没有索引时使用 OR 来代替 UNION。