首页 > 数据库 >10条SQL优化技巧

10条SQL优化技巧

时间:2023-08-05 18:03:43浏览次数:30  
标签:10 技巧 索引 user SQL where order select name

一、一些常见的SQL实践

(1)负向条件查询不能使用索引

select * from order where status!=0 and stauts!=1

not in/not exists都不是好习惯

可以优化为in查询:

select * from order where status in(2,3)

(2)前导模糊查询不能使用索引

select * from order where desc like ‘%XX’

而非前导模糊查询则可以:

select * from order where desc like ‘XX%’

(3)数据区分度不大的字段不宜使用索引

select * from user where sex=1

原因:性别只有男,女,每次过滤掉的数据很少,不宜使用索引。

经验上,能过滤80%数据时就可以使用索引。对于订单状态,如果状态值很少,不宜使用索引,如果状态值很多,能够过滤大量数据,则应该建立索引。

(4)在属性上进行计算不能命中索引

select * from order where YEAR(date) < = ‘2017’

即使date上建立了索引,也会全表扫描,可优化为值计算:

select * from order where date < = CURDATE()

或者:

select * from order where date < = ‘2017-01-01’

二、并非周知的SQL实践

(5)如果业务大部分是单条查询,使用Hash索引性能更好,例如用户中心

select * from user where uid=?

select * from user where login_name=?

原因:

B-Tree索引的时间复杂度是O(log(n))

Hash索引的时间复杂度是O(1)

(6)允许为null的列,查询有潜在大坑

单列索引不存null值,复合索引不存全为null的值,如果列允许为null,可能会得到“不符合预期”的结果集

select * from user where name != ‘shenjian’

如果name允许为null,索引不存储null值,结果集中不会包含这些记录。

所以,请使用not null约束以及默认值。

(7)复合索引最左前缀,并不是值SQL语句的where顺序要和复合索引一致

用户中心建立了(login_name, passwd)的复合索引

select * from user where login_name=? and passwd=?

select * from user where passwd=? and login_name=?

都能够命中索引

select * from user where login_name=?

也能命中索引,满足复合索引最左前缀

select * from user where passwd=?

不能命中索引,不满足复合索引最左前缀

(8)使用ENUM而不是字符串

ENUM保存的是TINYINT,别在枚举中搞一些“中国”“北京”“技术部”这样的字符串,字符串空间又大,效率又低。

三、小众但有用的SQL实践

(9)如果明确知道只有一条结果返回,limit 1能够提高效率

select * from user where login_name=?

可以优化为:

select * from user where login_name=? limit 1

原因:

你知道只有一条结果,但数据库并不知道,明确告诉它,让它主动停止游标移动

(10)把计算放到业务层而不是数据库层,除了节省数据的CPU,还有意想不到的查询缓存优化效果

select * from order where date < = CURDATE()

这不是一个好的SQL实践,应该优化为:

$curDate = date(‘Y-m-d’);

$res = mysql_query(

'select * from order where date < = $curDate');
  • 1

原因:

释放了数据库的CPU

多次调用,传入的SQL相同,才可以利用查询缓存

(11)强制类型转换会全表扫描

select * from user where phone=13800001234

你以为会命中phone索引么?大错特错了,这个语句究竟要怎么改?

末了,再加一条,不要使用select *(潜台词,文章的SQL都不合格 =_=),只返回需要的列,能够大大的节省数据传输量,与数据库的内存使用量哟。

标签:10,技巧,索引,user,SQL,where,order,select,name
From: https://blog.51cto.com/u_16207938/6976761

相关文章

  • INS-10013:安装程序检测到此系统的中央资源清册中未注册当前home
    错误信息【汉】INS-10013:安装程序检测到此系统的中央资源清册中未注册当前home【英】INS-10013:Theinstallerhasdetectedthatcurrenthomeisnotregisteredinthecentralinventoryonthissystem.例CentOS7操作系统中,在安装Oracle数据库软件时报错。版本Oracle【11.2.0.......
  • MySQL Server 5.5的安装及遇到问题记录
    一、安装安装没有什么说的,不会看图(版本,我选择自定义——Custom,供参考)                        --------------------------------------------------------------------------二、问题记录:安装后遇到的问题 1.安装mysql......
  • MySQL多实例
    MySQL多实例介绍应用场景:资金紧张公司若公司资金紧张,公司业务访问量不太大,但又希望不同业务的数据库服务各自能够尽量独立地提供服务而互相不受影响,或者,还有需要主从复制等技术提供备份或读写分离服务的需求,那么,多实例就再好不过了。用户并发访问量不大的业务当公司业务访问......
  • SQL分页优化三 降序排序+分页
    测试验证如下SQL:select*from(select*from(selecta.*,rownumrnfrom(select*fromtestorderbyobject_id,object_namedesc)a)whererownum<=10)wherern>......
  • SQL分页优化四 等值+非等值+order by分页
    测试验证现有如下SQL,每页显示10条:select*fromtestwhereowner='SYS'andobject_id>1000orderbyobject_name;select*from(select*from(selecta.*,rownumrnfrom(select*fromt......
  • SQL分页优化五 like+非等值+order by分页
    测试验证如下SQL:select*from(select*from(selecta.*,rownumrnfrom(select*fromtestwhereownerlike'SYS%'......
  • openGauss的SQL引擎在3.1.0版本中做了哪些优化?
    openGauss的SQL引擎在3.1.0版本中做了哪些优化?收录于合集#技术干货83个查询执行能力对数据库来说至关重要,这直接决定了查询语句生成的执行计划以何种方式进行执行,如果哪个执行算子的执行表现不好,将会对数据库的整体性能产生极大的影响。同时,执行算子的实现也极大考验一款数据库的工......
  • 数据库迁移系列】从MySQL到openGauss的数据库对象迁移实践
    数据库迁移系列】从MySQL到openGauss的数据库对象迁移实践原创酷哥[openGauss](javascript:void(0);)2022-11-0718:03发表于广东9月30日新发布的openGauss3.1.0版本,工具的全量迁移和增量迁移的性能不但有了全面提升,而且支持数据库对象视图、触发器、自定义函数、存储过程的......
  • 10.2 web服务器
    Web客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫做HTTP(HypertextTransferProtocol,超文本传输协议)。HTTP是一个简单的协议。一个Web客户端(即浏览器)打开一个到服务器的因特网连接,并且请求某些内容。服务器响应所请求的内容,然后关闭连接。浏览器读取这些内容,并把......
  • SQL-去除最大值与最小值求均值的问题
    背景今天有同事问我一道关于数据库SQL的面试题,我刚开始随便给了一个思路,后来思索发现这个思路有漏洞,于是总结下来,仅供参考。问题:薪水表中是员工薪水的基本信息,包括雇员编号,和薪水,查询除去最高、最低薪水后的平均薪水。一、薪水表信息CREATETABLE`salaries`(`emp_n......