设为首页 收藏本站
查看: 889|回复: 0

[经验分享] sql 查询优化准则

[复制链接]

尚未签到

发表于 2016-11-11 09:36:55 | 显示全部楼层 |阅读模式
  根据我们的经验(由很多业界专家证明),在 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;
[size=0.76em]比较复杂的情况,根据集合的摩根定理:


NOT( A AND B) = (NOT A) OR (NOT B) 和 NOT(A OR B) = (NOT A) AND (NOT B)
  IN 比 多个OR要快。
  当 IN 操作符,是一系列密集的整型数字时,最好是查找哪些值不符合条件,而不是查找哪些值符合条件,因此,如下的查询条件就应该进行如下的转换:
  UNION 用来合并两个结果集但是或过滤重复的值,UNION ALL则不会过滤重复的值。
[size=0.76em]查询 1:



SELECT * FROM Table1
WHERE column1 = 5
UNION
SELECT * FROM Table1
WHERE column2 = 5

  

[size=0.76em]查询 2:



SELECT DISTINCT * FROM Table1
WHERE column1 = 5
OR column2 = 5

[size=0.76em]在上面的例子中,column1 和 column2 都没有索引。如果查询 2 总是比查询 1 执行的快的话,那么就可以建议总是将查询 1 转换成查询 2,但是有一种情况,这样做在一些数据库系统中可能会带来性能变差,这是由于两个优化缺陷所造成的。

[size=0.76em]第一个优化缺陷就是很多优化器只优化一个 SELECT 语句中一个 WHERE 语句,所以查询 1 的两个 SELECT 语句都被执行。首先优化器根据查询条件 column1 = 5 为真来查找所有符合条件的所有行,然后据查询条件 column2 = 5 为真来查找所有符合条件的所有行,即两次表扫描,因此,如果 column1 = 5 没有索引的话,查询 1 将需要 2 倍于查询 2 所需的时间。如果 column1 = 5 有索引的话,仍然需要二次扫描,但是只有在某些数据库系统存在一个不常见的优化缺陷却将第一个优化缺陷给弥补了。当一些优化器发现查询中存在 OR 操作符时,就不使用索引查询,所以在这种情况下,并且只有在这种情况下,UNION 才比 OR 性能更高。这种情况很少见,所以仍然建议大家当待查询的列没有索引时使用 OR 来代替 UNION。

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298751-1-1.html 上篇帖子: 数据库常用SQL 下篇帖子: SQL注入漏洞与参数化查询
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表