SQL查询优化实践
为什么要优化
- 系统的吞吐量瓶颈往往出现在数据库的访问速度上,即随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢,且数据是存放在磁盘上的,读写速度无法和内存相比
如何优化
- 设计数据库时:数据库表、字段的设计,存储引擎
- 利用好MySQL自身提供的功能,如索引,语句写法的调优
- MySQL集群、分库分表、读写分离
关于SQL语句的优化的方法方式,网络有很多经验,所以本文抛开这些,设法在DAO层的优化和数据库设计优化上建树,并列举两个简单实例
例子1:ERP查询优化
现状分析:
1 缺少关联索引
2 Mysql本身的性能所限,对多个表的关联支持不好,目前的性能主要集中在列表查询上面,列表查询关联了很多表
应对方法:
1 增加必要的索引:通过explain查看执行记录,根据执行计划添加索引;
2 先统计业务数据主表主键,获取较小结果集,然后再利用结果集关联查询;
1) 先根据主表和条件查询显示业务数据的主键
2) 根据主键作为查询条件,再关联其他关联表,查询需要的业务字段
3) 在主表查询时,针对需要关联其他表的查询条件,需要做只有设置这个条件,才会做表关联的设置
例如 有如下表 TT_A TT_B TT_C TT_D 假设未优化前的SQL是这样的 SELECT
A.ID,
....
B.NAME,
.....
C.AGE,
....
D.SEX
..... FROM TT_A A
LEFT JOIN TT_B B ON A.ID = B.ITEM_ID
LEFT JOIN TT_C C ON B.ID = C.ITEM_ID
LEFT JOIN TT_D D ON C.ID = D.ITEM_ID
WHERE 1=1
AND A.XX = ?
AND A.VV = ?
..... 那么优化后的SQL是 第一步 SELECT
A.ID FROM TT_A A
WHERE 1=1
AND A.XX = ?
AND A.VV = ? 第二步 SELECT
A.ID,
....
B.NAME,
.....
C.AGE,
....
D.SEX
.....
FROM ( SELECT A.ID,..... FROM TT_A WHERE ID IN (1,2,3..) ) A
LEFT JOIN TT_B B ON A.ID = B.ITEM_ID
LEFT JOIN TT_C C ON B.ID = C.ITEM_ID
LEFT JOIN TT_D D ON C.ID = D.ITEM_ID
WHERE 1=1
AND A.XX = ?
AND A.VV = ?
小结:
这种优化适用于,列表查询,因为一个列表查询的条件一般都是和主表挂钩的,所以利用这一点,建立关键字段索引,同时通过查询条件的限制大大的缩小主表的数据量。这样关联其他表的时候就会快的多
例子2:文章搜索优化
假设你要做个贴吧的文章搜索功能,最简单直接的存储结构,就是利用关系数据库,创建这样一个存储文章的关系数据库表 TT_ARTICLES:
那么,假如现在的搜索关键字是“目标”,我们就可以利用字符串匹配的方式来对 CONTENT 列进行匹配查询:
select * from ARTICLES where CONTENT like '% 目标 %';
这很容易就实现了搜索功能。但是,这样的方式有着明显的问题,即使用 % 来进行字符串匹配是非常低效的,因此这样的查询需要遍历整个表(全表扫描)。几篇、几十篇文章的时 候,还不是什么问题,但是如果有几十万、几百万的文章,这种方式是完全不可行的。且不说单独的关系数据库表就不能容纳那么大的数据了,就是能够容纳,要扫描一遍,这里的时间代价是难以想象的
于是,我们就要引入“倒排索引”的技术了。在前面所述的场景下, 我们可以把这个概念拆分为两个部分来解释: 好,那上面的 ARTICLES 表依然存在,但现在需要添加一个关键字表 KEYWORDS,并且,KEYWORD 列需要添加索引,因此这条关键字的记录可以被迅速找到:
当然,我们还需要一个关联关系表把 KEYWORDS 表和 ARTICLES 表结合起来, KEYWORD_ID 和 ARTICLE_ID 作为联合主键
你看,这其实是一个多对多的关系,即同一个关键字可以出现在多篇文章中,而一篇文章可 以包含多个不同的关键字。这样,我们可以先根据被索引了的关键字,从 KEYWARDS 表 中找到相应的 KEYWORD_ID,进而根据它在上面的关联关系表找到 ARTICLE_ID,再根据 它去 ARTICLES 表中找到对应的文章。
小结:
这看起来是三次查找,但是因为每次都走索引,就免去了全表扫描,在数据量较小的时候速 度并不慢,并且,在使用 SQL 实现的时候,这个过程完全可以放到一个 SQL 语句中。在数 据量较小的时候,上面的方法已经足够好用了。 这样解决了全表扫描和字符串 % 匹配查询造成的性能问题。
总结:
在技术面试的时候,如果你能举出实际的例子,或者是直接说自己开发过程的问题和收获会让面试分会加很多,回答逻辑性也要强一点,不要东一点西一点,容易把自己都绕晕的。例如,问为怎么优化SQL你不要一上来就直接回答加索引,你可以这样回答:
面试官您好,首先我们的项目DB数据量遇到了瓶颈,导致列表查询非常缓慢,给用户的体验不好,为了解决这个问题,有很多种方法,例如最基本的数据库表设计,基本的SQL优化,MYSQL的集群,读写分离,分库分表,架构上增加缓存层等,他们的优缺点……,综合这些然后再结合我们项目特点,最后我们在技术选型的时候选了谁。
如果你这样有条不紊,有理有据的回答了问题而且还说出这么多问题外的知识点,面试官会觉得你不只是一个会写代码的人,而是你逻辑清晰,你对技术选型,有自己的理解和思考
SQL查询优化实践的更多相关文章
- SQL查询优化 LEFT JOIN和INNER JOIN
作者:VerySky 推荐:陈敬(Cathy) SQL查询优化 LEFT JOIN和INNER JOIN 1,连接了八个数据库表,而且全部使用LEFT JOIN,如下所示: Resource_Reso ...
- SQL查询优化——数据结构设计
本文部分内容会涉及mysql,可能在其它数据库中并不适用. 本章节仅仅针对数据库结构设计做讨论.查询优化的其它内容待续. 数据库设计及使用是WEB开发程序猿必备的一项基础技能,在大数据量和高并发场景, ...
- 引用:初探Sql Server 执行计划及Sql查询优化
原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想 ...
- 30条SQL查询优化原则
在我们平常的SQL查询中,其实我们有许多应该注意的原则,以来实现SQL查询的优化,本文将为大家介绍30条查询优化原则. 首先应注意的原则 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 wher ...
- MySQL 性能调优——SQL 查询优化
如何设计最优的数据库表结构,如何建立最好的索引,以及如何扩展数据库的查询,这些对于高性能来说都是必不可少的.但是只有这些还不够,要获得良好的数据库性能,我们还要设计合理的数据库查询,如果查询设计的很糟 ...
- MySQL SQL查询优化技巧详解
MySQL SQL查询优化技巧详解 本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...
- 《打造扛得住的MySQL数据库架构》第7章 SQL查询优化
SQL查询优化 7-1 获取有性能问题SQL的三种方法 如何设计最优的数据库表结构 如何建立最好的索引 如何拓展数据库的查询 查询优化,索引优化,库表结构优化 如何获取有性能问题的SQL 1.通过测试 ...
- 大数据量高并发的数据库优化,sql查询优化
一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...
- 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
转自http://blog.163.com/zhangjie_0303/blog/static/9908270620146951355834/ 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 w ...
随机推荐
- LaTeX常用篇(三)---矩阵与表格
目录 1. 序言 2. 矩阵 2.1 复杂写法 2.2 简化写法 2.3 复杂矩阵 3. 表格 4. 对齐 更新时间:2019.10.02 1. 序言 矩阵是一个强大的工具,许多东西都能够用矩阵来 ...
- 代码传奇 | 身价10亿的程序员 雷军当年也为他打工——WPS之父 求伯君
他的前半生,值得我们每一个人深思. 在普通人眼里,他寂寂无名,只有年岁稍长的文化人,才听说过他传奇般的存在. 在IT人眼里,他是块活化石,中国第一的大旗除了他,没人敢抗! 他是求伯君,从一个浙江穷山村 ...
- Apache中Cookie长度的设置 414 request-uri too large apache
起因: 今天在调试Ucenter的同步登陆和同步登出的过程中,浏览器突然出现以下错误提示: Your browser sent a request that this server could not ...
- iOS 原生库对 https 的处理
转载自:swift cafe 使用 NSURLSession NSURLSession 是 iOS 原生提供的网络处理库.它提供了丰富的接口以及配置选项,满足我们平时网络处理的大部分需求,同时它也支持 ...
- Jquery动态bind绑定已有函数,函数自动执行的问题解决方法
在bind后面的方法,不能带括号,带括号函数就自动执行了... <script> //通过子元素删除某行 function deleteRow() { var flag = confirm ...
- (Java) 模拟http请求调用远程接口
package com.vcgeek.hephaestus.utils; import java.io.BufferedReader; import java.io.IOException; impo ...
- Web for pentester_writeup之LDAP attacks篇
Web for pentester_writeup之LDAP attacks篇 LDAP attacks(LDAP 攻击) LDAP是轻量目录访问协议,英文全称是Lightweight Directo ...
- NOIP模拟13
上来看了一遍题,发现T2似乎不可做...暴力只给20分怎么玩? T1感觉是要离线处理,但是看了一会发现不会,遂决定先打暴力.然后去把T2 20分拿了,回去看T1,手摸了一下样例,成功推出式子,5分钟码 ...
- 《吊打面试官》系列-Redis哨兵、持久化、主从、手撕LRU
你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难.作为一个在互联 ...
- 没NOIP了?
HSEZ李亮:“考虑一下来HSEZ当艺术生吧!"