提高mysql千万级大数据SQL查询优化30条经验
csdh11 2025-01-02 15:31 4 浏览
1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
3、应尽量避免在 where 子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。
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、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
6、下面的查询也将导致全表扫描:
select id from t where name like '李%'
若要提高效率,可以考虑全文检索。
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 name like 'abc%'
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、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
相关推荐
- 重温2010年总决赛,黄绿大战,科比真的抢了加索尔FMVP吗
-
2010年NBA总决赛,已经过去了10多年。不过,提起那一年的总决赛,很多球迷还是记忆犹新,在他们心里,这一年的总决赛是21世纪以来最为精彩的一次总决赛。2010年总决赛,凯尔特人和湖人时隔2年再次相...
- 始料未及的屠戮——简述2010世界杯阿根廷德国之战
-
2010年四分之一决赛,德国队以一个令人震惊的比分击败阿根廷,追平连续3届闯进半决赛的纪录,同时创造12次入围4强的新纪录。如果论及世界杯中的冤家球队,英格兰和阿根廷是一对,巴西和法国是一对,阿根廷和...
- 10年总决赛湖人4:3凯尔特人——科比和加索尔每场具体数据
-
以下7图为2009-2010赛季总决赛湖人4:3凯尔特人——科比和加索尔每场具体数据:湖人首发:安德鲁·拜纳姆、保罗·加索尔、梅塔·沃尔德·皮斯(慈世平)、...
- 2020年和2010年的热刺相比,到底提高了多少?
-
虽然本赛季状态并不太好,但近些年托特纳姆热刺在各方面应该说有了很大的进步。按照这个思路,我们来比较一下热刺在2010年和如今的一下数据。联赛位置2009/2010赛季是热刺崛起的开始,他们逐渐成为联赛...
- 2010季后赛詹姆斯VS罗斯 老詹关键三分锁定胜局
-
直播吧6月6日讯2010年季后赛克利夫兰骑士与芝加哥公牛在首轮相遇。整个系列赛,身为当赛季常规赛MVP的詹姆斯场均得到31.8分9.2篮板8.2助攻,而刚进入联盟两年的罗斯亦表现抢眼场均贡献26.8...
- 攻势犀利未翻盘,出线希望变暗淡,韩国不敌加纳离16强远了
-
来源:环球时报【环球时报驻埃及特派记者黄培昭环球时报特约记者李佳寅唐牧茂】北京时间28日晚,韩国队在世界杯H组第二轮比赛中2∶3不敌加纳队,这是两支球队在世界杯赛场上的首次碰面。两支球队此前...
- VC++与MFC入门简介:它们的区别是什么&如何挑选开发组件
-
C++编程入门系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的了解了。但是教程中讲的例子只是一个个简单的例程,并没有可视化窗口。在这套VS2010/MFC编程入门教...
- 哪款C语言编译器(IDE)适合初学者?
-
这里我们把“编译器”和“IDE(集成开发环境)”当做一个概念,不再加以区分。C语言的集成开发环境有很多种,尤其是Windows下,多如牛毛,初学者往往不知道该如何选择,本节我们就针对Window...
- 八强硬碰硬 往事涌心头
-
晨报记者孙俊毅北京时间昨天凌晨,随着欧洲杯最后两场1/8决赛结束,八强球队全部产生:上半区的4支球队为瑞士、西班牙、比利时和意大利,下半区的4支球队则是捷克、丹麦、英格兰和乌克兰。1/4决赛将于北京...
- 无缘十四年后顶峰相遇!10年世界杯决赛荷兰vs西班牙,还记得吗?
-
欧洲杯半决赛荷兰队无缘与西班牙顶峰相遇,被英格兰所淘汰。荷兰队2010年世界杯决赛正是和西班牙对决,当时0-1惜败巅峰西班牙。(欢迎大家点点关注,随老相馆一起追忆往昔)...
- (2)初学C++:如何使用Visual Stdio 2010调试C++程序?
-
一、创建解决方案和项目1.打开Vs2010,单击...
- 「连载」 .Net cad二次开发(一)
-
平常都用arx/c++/mfc来进行cad开发,业余时间学习下.net/C#开发,在此做下记录,同时以供大家参考,交流,共同进步。ps:我也是现学的,如果有什么不对的地方可以指出来,在此谢谢大家!!一...
- 今日图集:2010年湖人VS热火圣诞大战
-
詹姆斯撒镁粉科比面对詹姆斯跳投科比防守詹姆斯詹姆斯、丹皮尔、科比韦德飞身上篮科比对抗韦德詹姆斯与阿泰斯特奥多姆与波什...
- Visual Studio 2010(VS)--消消乐定制版?--添加反应计时
-
VisualStudio2010(VS)--消消乐定制版?--添加反应计时上期回顾(上期主要是把原来16格,扩展到了36格的,带18组文字图形的消消乐):本期将给他加一个计时,就是当第一次按下的时...
- 【项目实战】C/C++自制程序:双人击球游戏
-
每天一个编程小项目,提升你的编程能力!游戏说明Player1玩家通过W、S按键控制左板上下移动,Player2玩家通过O、L按键控制右板上下移动。在游戏过程中,小球的速度会随着接触木板的次...
- 一周热门
-
-
一文读懂关于MySQL Datetime字段允许插入0000-00-00无效日期
-
一款全能的看图软件,速度快、功能强、免费用
-
Boston Dynamics Founder to Attend the 2024 T-EDGE Conference
-
IDC机房服务器托管可提供的服务
-
新版腾讯QQ更新Windows 9.9.7、Mac 6.9.25、Linux 3.2.5版本
-
Serv-u 提权
-
一文看懂mysql时间函数now()、current_timestamp() 和sysdate()
-
详解PostgreSQL 如何获取当前日期时间
-
流星蝴蝶剑:76邵氏精华版,强化了流星,消失了蝴蝶
-
「PS教程」PS入门笔记!新手必备
-
- 最近发表
- 标签列表
-
- huaweiupdateextractor (27)
- mysql 时间索引 (31)
- mydisktest_v298 (34)
- sql 日期比较 (26)
- document.appendchild (35)
- 头像打包下载 (61)
- acmecadconverter_8.52绿色版 (39)
- oracle timestamp比较大小 (28)
- word文档批量处理大师破解版 (36)
- server2016安装密钥 (33)
- mysql 昨天的日期 (37)
- 加密与解密第四版pdf (30)
- jemeter官网 (31)
- parsevideo (33)
- 个人网站源码 (37)
- ckeditor4中文文档 (27)
- exe4j_java_home (30)
- centos7.4下载 (33)
- xlsx.full.min.js下载 (32)
- 深度学习 pdf (28)
- mysql 查询今天的数据 (34)
- intouch2014r2sp1永久授权 (36)
- 先锋影音源资2019 (35)
- usb2.0-serial驱动下载 (30)
- vs2010官网 (31)