作为一名程序员,少不了要写一些sql语句,但每个人写出来的sql执行效率还是有差距的,功力深厚的人,写的sql简洁而且高效,初学者,往往只是实现功能,至于性能问题,可能无从下手。在这里我将之前在sql优化方面的一些技巧和高效写法,给大家总结了一下,不说能百分百解决sql性能问题,基本上能解决百分之八十以上的sql性能问题。

in子查询优化

原始语句

select a.depno,a.status from t_test_1 a where a.depno in (select b.depno from t_test_2 b where b.name='test')

一般功力稍微深厚一点的人,会将in改写成exists

select a.depno,a.status from t_test_1 a where exists (select 1 from t_test_2 b where a.depno=b.depno and b.name='test')

但是这种写法不是最优的写法,性能最高的写法是将in改成inner join

select a.depno,a.status from t_test_1 a inner join t_test_2 b on a.depno=b.depno where b.name='test'select a.depno,a.status from t_test_1 a inner join (select depno from t_test2 where name='test') b on a.depno=b.depno

in非子查询优化

有很多业务场景 ,例如要查询某些订单状态,就有如下sql语句

select a.orderid,a.status from t_order a where a.status in (3,4,5)

大家都知道sql语句走索引,可以用range scan方式去扫描索引,那可以将in改写成>=,<=

select a.orderid,a.status from t_order a where a.status >=3 and a.status <=5

还有一种方式,将in改写成=

select a.orderid,a.status from t_order a where a.status=3union allselect a.orderid,a.status from t_order a where a.status=4union allselect a.orderid,a.status from t_order a where a.status=5

这种写法之后,你的sql语句就会走索引,执行效率会提升很大,当然这种写法只适合某些特定的业务场景

like语句优化

有一些业务场景需要用到like去做查询条件,例如

select a.orderid,a.status from t_order a where a.orderid like '%20190108%'

这个写法,在因为第一个字符是通配符,会不走索引,导致查询效率非常差,在这里强烈建议首字符,不要使用通配符

select a.orderid,a.status from t_order a where a.orderid like '20190108%'

隐式转换

在数据库里,有时候会将字符串隐式转成数字,然后进行比较,在这里举一个例子来说明

mysql> show create table t_testG;*************************** 1. row ***************************       Table: t_testCreate Table: CREATE TABLE `t_test` (  `id` char(10) NOT NULL,  `status` char(1) DEFAULT NULL,  `name` char(20) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)mysql> explain select * from t_test where status='1';+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+| id | select_type | table  | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+|  1 | SIMPLE      | t_test | NULL       | ref  | status        | status | 4       | const |    2 |   100.00 | NULL  |+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+1 row in set, 1 warning (0.00 sec)mysql> mysql> explain select * from t_test where status=1;+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+|  1 | SIMPLE      | t_test | NULL       | ALL  | status        | NULL | NULL    | NULL |    5 |    20.00 | Using where |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 3 warnings (0.00 sec)

看到了吧,查询条件用status=1的时候,你的select语句是不走索引的,这是因为数据库将status取出来的字符串隐式转换成数字,然后再去过滤数据,我换一个种写法,可能更清晰明了

mysql> explain select * from t_test where CAST(status AS SIGNED)=1;+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+|  1 | SIMPLE      | t_test | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | Using where |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)

这个隐式转换,相当于在status用cast做一次字符串到数字转换,因为字段上用了函数,因此是不会走索引的。大家在写sql语句的时候,一定要注意这个隐式转换,在日常运维过程中,碰到很多这种坑。

is null优化

对于写sql还在用is null的同学,我无话可说,要不就是前人给你挖的坑,要不就是你自己给自己挖的坑,如果是前者还能理解,如果是后者,真的不值得同情。在此特别强调,在建表或者添加字段时,每个字段都必须有默认值,这样你写sql语句时,就不需要用is null这种写法,只要你用=做查询条件,就有办法去走索引,提升查询效率。

or优化

在这里还是举上面的例子

select a.orderid,a.status from t_order a where a.status =4 or a.status=5

类似这种sql语句,优化还是很简单,将其改成union all方式即可

select a.orderid,a.status from t_order a where a.status =4 union allselect a.orderid,a.status from t_order a where a.status =5

还有一些sql语句优化方法和技巧,下次再给大家分享。

修改 decimal 默认值为0.00 sql_书写高性能SQL语句技巧,网友都说好相关推荐

  1. 修改 decimal 默认值为0.00 sql_被经理邀请去“爬山”,只是因为我写错了一条SQL语句?...

    作者:isysc1 链接:https://juejin.im/post/5f06a2156fb9a07e5f5180df 来源:掘金 前戏 SQL 写的妙,涨薪呱呱叫! 新来的实习生小杨写了一条 SQ ...

  2. mysql增加字段设默认值_mysql原表增加字段且设置默认值及修改字段默认值

    -- 增加字段及注释 alter table sr_zjff_main add zjbzjxbj int(1) DEFAULT '0' COMMENT ''; alter table sr_main_ ...

  3. SqlServer 增加字段,修改字段名,删除字段,修改字段默认值

    SqlServer 增加字段,修改字段名,删除字段,修改字段默认值 1:增加字段 语法:alter table 表名 add 新增字段名 字段类型 默认值- 2:修改字段名 语法:exec sp_re ...

  4. Mysql 修改字段默认值问题

    临下班前,测试测出所有的返回报文中有一个版本号的值没有上送,最后定位是由于数据库配置表里版本号是空. 这应该属于前辈们留下的bug了.... 首先试了下 ALTER TABLE newftp alte ...

  5. JAVA中stacksize是什么意思_【Java Thread StackSize】如何理解Java中Thread构造器中的stackSize的默认值为0?...

    Thred的stackSize默认值 e-mail:rolltion.zhang@foxmail.com 前言:为什么要研究默认值 在Java和Java开发框架中,我们经常会遇到一系列的默认值,尽管他 ...

  6. int默认值为0,Integer默认值为null

    前提概要 Java为每个原始类型提供了封装类,Integer是java为int提供的封装类.         int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和 ...

  7. mysql5.7 datetime 默认值为‘0000-00-00 00:00:00‘值无法创建问题解决

    mysql5.7 datetime 默认值为'0000-00-00 00:00:00'值无法创建问题解决 参考文章: (1)mysql5.7 datetime 默认值为'0000-00-00 00:0 ...

  8. html编辑器增加超级链接,ueditor1.2.1修改超链接默认值,ueditor编辑器新窗口打开连接...

    ueditor1.2.1修改超链接默认值 首先超链接的文件是在ueditor目录中的dialogs目录中的link目录的link.html 如图: 然后在链接地址或标题上加value属性和值,希望在新 ...

  9. SQL语句修改字段默认值

    一.SQL语句修改字段默认值 alter table 表名 drop constraint 约束名字 说明:删除表的字段的原有约束 alter table 表名 add constraint 约束名字 ...

最新文章

  1. 阿里某员工面试华为后吐槽:面试官太水,反问几句都答不上来
  2. HP380G7服务器安装fedaro16的问题解决
  3. 【 FPGA 】设置多周期路径约束
  4. SharePoint 2010 沙盒解决方案以及 Visual Studio 2010 模板
  5. DNS子域委派配置案例[转载]
  6. Java 笔试题集锦
  7. bulkwrite 批量插入_使用SqlBulkCopy批量插入数据
  8. 后退返回命令数量_Redis | Redis 有序集合相关命令
  9. python画二次函数图像的顶点_画二次函数图像的步骤
  10. Java EE 8 MVC:控制器的详细介绍
  11. oracle安装后新建数据库实例及配置
  12. OSPF次末节区域配置 201
  13. 怎么查redis 中的 cache_20、springcloud如何使用spring-cache
  14. 鸿蒙比苹果流畅,华为鸿蒙应用恢复率优于苹果iOS,无惧老化36个月持续流畅
  15. CSUOJ 1197- Staginner 买葡萄
  16. [置顶]       jBPM4工作流开发实战 之 第二部分 jBPM4开发入门
  17. 把几个任务分配到几个设备上的代码
  18. Windows内核学习------双机调试的安装(物理机win10,虚拟机win7,虚拟机软件vmware)
  19. 太极熊猫3服务器维护中,太极熊猫3月10日维护公告_瑞兽稀有技修改_蚕豆网新闻...
  20. 北京大学生物信息学(9)第二代基因组测序技术

热门文章

  1. 为Autodesk Viewer添加自定义工具条
  2. Session赋值(备注)
  3. WCF使用Json传输的一个BUG
  4. POJ 2763 Housewife Wind【LCA_RMQ+树状数组】
  5. Asp.Net WebApi swagger使用教程
  6. 红皮书:变量、作用域和内存问题(四)
  7. JavaScript DOM编程艺术第一章:JavaScript简史
  8. Atitit.eclipse git使用
  9. sql 遍历结果print和表格形式
  10. localStorage 简单示例