MySQL中优化sql语句查询常用的30种方法_php mysql sql语句优化经典小技巧-程序员宅基地

浅谈MySQL中优化sql语句查询常用的30种方法

作者: 字体:[增加 减小] 类型:转载 时间:2013-06-28 我要评论

本篇文章是对MySQL中优化sql语句查询常用的30种方法进行了详细的分析介绍,需要的朋友参考下
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20

5.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
若要提高效率,可以考虑全文检索。

6.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2

9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(...)

13.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)

14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

30.尽量避免大事务操作,提高系统并发能力。  
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pgyphp/article/details/50379590

智能推荐

Android:利用Java反射调用@hide的API_connectivitymanager 反射-程序员宅基地

文章浏览阅读1.6w次,点赞4次,收藏13次。设置使用3G数据功能:从源代码看到隐藏的API(ConnectivityManager.java): /** * Sets the persisted value for enabling/disabling Mobile data. * * @param enabled Whether the mobile data connection should_connectivitymanager 反射

[渝粤教育] 中国地质大学 互换性与测量技术 复习题 (2)_要求两孔同轴度φ0.3mm最大偏差是多少-程序员宅基地

文章浏览阅读941次。《互换性与测量技术》模拟题一.单选题1.优先选用基孔制的原因是().A.孔比轴难加工B.减少定尺寸孔用刀具量具的规格和数量C.减少孔和轴的公差带数量D.从工艺上讲应先加工孔后加工轴2.评定齿轮传递运动准确性的指标是().A.齿距累积总偏差B.单个齿距偏差C.齿廓总偏差D.螺旋线总偏差3.当几何公差框格的指引线箭头与尺寸线对齐时所表示的被测要素是().A.轮廓要素B.单一要素C.中心要素D.基准要素4.螺纹代号M20×2-7g6g表示的螺纹是().A.粗牙普通外螺纹B.粗_要求两孔同轴度φ0.3mm最大偏差是多少

Simulink模型转为TwinCAT3可以运行的ST程序_simulink导入到twincat-程序员宅基地

文章浏览阅读1k次。@Simulink PLC Coder :将Simulink模型转为TwunCAT程序1 先把simulink程序封装为一个子系统subsystem,标注好输入输出端口参考链接:https://ww2.mathworks.cn/help/plccoder/ug/plc-coder-general.html#bsemuq2-12 程序内不能包含任何连续状态的模块(比如微分,积分模块),而且有不支持的等simulink模块(比如Clock模块),因此需要用离散状态的功能块替代,或者编写MATLAB _simulink导入到twincat

程序员35岁真的是分水岭吗?复习指南_程序员35岁为什么会是一个分水岭-程序员宅基地

文章浏览阅读100次。缘起随着互联网企业的不断发展,产品项目中的模块越来越多,用户体验要求也越来越高,想实现小步快跑、快速迭代的目的越来越难,还有应用之间的互相调用等等问题,插件化技术应用而生。如果没有插件化技术,美团、淘宝这些集成了大量“app”的应用,可能会有几个g那么大。所以,当今的Android移动开发,不会热修复、插件化、组件化,80%以上的面试都过不了。阿里P8大佬每天熬夜到凌晨一两点,花了将近半个月时间将Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、_程序员35岁为什么会是一个分水岭

echarts全国地图点击弹窗(Vue)_echarts地图点击弹出窗体明细-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏18次。实现echart 全国地图点击标记有弹窗_echarts地图点击弹出窗体明细

408计组大题-----I/O大题(二)_异步串行通信方式408-程序员宅基地

文章浏览阅读309次。本题第(1)题所考的I/O模式为程序中断方式,我们做如下对知识点的回顾:1.I/O接口的数据缓冲区满,I/O接口给CPU发送I/O中断信号,CPU检测到I/O中断后进行中断处理①中断响应(中断隐指令)②中断服务程序程序中断方式的CPU取数据时间 = ① + ②本题第(2)题所考的I/O模式为DMA方式,我们做如下对知识点的回顾:1.I/O接口与主机之间交换数据方式为以块为单位,I/O设备与I/O接口交换数据方式为以字为单位,传输过程为。_异步串行通信方式408

随便推点

Win10解决Disciples 2圣战群英传2卡顿问题_disciples 2如何窗口化运行-程序员宅基地

文章浏览阅读5.9k次。最近想翻点老游戏出来玩,比如圣战群英传2,但是卡得我mmp,一通搜索和捣鼓之后,终于发现了比较简单的解决问题的方法。1、首先确认电脑中是否有vcredist2010,至少08年以后的VC++库,没有就安。2、检查游戏根目录下有没有d3d9.dll,没有就下方传送门。https://dl.pconline.com.cn/download/91252.html如果还没能解决问题,那么:3、看看根目录有没有Disciple.ini,如果没有:3.1、看看根目录有没有一个骷髅头头像的Importer.e_disciples 2如何窗口化运行

数据链路层循环冗余(CRC)检验_链路层循环冗余校验码是检验哪一部分-程序员宅基地

文章浏览阅读5.5k次。数据链路层有许多协议,但有三个基本问题是相同的:封装成帧、透明传输和差错检验。为了保证数据传输的可靠性,在计算机网络传输数据时,必须采用各种差错检验措施,目前广泛使用的是循环冗余(CRC)检验的检错技术。 CRC检验原理: 在发送端,先把数据划分为组,假定每个组k个比特。现假定待传送的数据M=101001(k=6)。CRC运算就是在数据M后面添加供差错检验用的n位冗余码,然后构成一个帧发送出去,_链路层循环冗余校验码是检验哪一部分

Spring Security(08)——intercept-url配置_intercept-url j_spring_security_logout-程序员宅基地

文章浏览阅读1w次。Spring Security介绍系列文章。本文主要介绍如何通过intercept-url配置来实现对特定的URL进行拦截,包括指定访问权限、指定访问协议、指定请求方法_intercept-url j_spring_security_logout

iserdese2接口详解_Xilinx 7系列FPGA之SelectIO(3)——高级IO逻辑资源简介-程序员宅基地

文章浏览阅读1.7k次。上一篇咱们介绍了IO逻辑资源,本篇咱们来聊一聊高级的IO逻辑资源,即ISERDESE2模块和OSERDESE2模块。所谓ISERDESE2模块,即Input serial-to-parallel converters。该模块的作用就是实现高速源同步输入数据的串并转换。所谓OSERDESE2模块,即output parallel-to-serial converters。该模块的作用就是实现高速源同..._iserdese2用法

服务没有注册到nacos的原因分析_服务注册不到nacos-程序员宅基地

文章浏览阅读6.9k次,点赞9次,收藏4次。服务没有注册到nacos的原因分析因为没有加上版本号,导致不能注册。 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>0.2.1.RELEASE<_服务注册不到nacos

Android应用去掉标题栏状态栏(Android Studio)_android studio 应用禁用状态栏-程序员宅基地

文章浏览阅读442次。**网上关于Android Studio的教程比较少,去掉标题栏的方法大多不能直接使用。 在Android Studio中其实更简单一些,在app/res/values/styles.xml文件中加个标签就可以了**true 完整代码如下,可以看到这段代码放在什么位置。

推荐文章

热门文章

相关标签