sql优化

Mysql常规优化

回眸只為那壹抹淺笑 提交于 2020-02-27 08:58:58
一、SQL语句优化 (1)使用limit对查询结果的记录进行限定 (2)避免select *,将需要查找的字段列出来 (3)使用连接(join)来代替子查询 (4)拆分大的delete或insert语句 二、选择合适的数据类型 (1)使用可存下数据的最小的数据类型,整型 < date,time < char,varchar < blob (2)使用简单的数据类型,整型比字符处理开销更小,因为字符串的比较更复杂。如,int类型存储时间类型,bigint类型转ip函数 (3)使用合理的字段属性长度,固定长度的表会更快。使用enum、char而不是varchar (4)尽可能使用not null定义字段 (5)尽量少用text,非用不可最好分表 三、选择合适的索引列 (1)查询频繁的列,在where,group by,order by,on从句中出现的列 (2)where条件中<,<=,=,>,>=,between,in,以及like 字符串+通配符(%)出现的列 (3)长度小的列,索引字段越小越好,因为数据库的存储单位是页,一页中能存下的数据越多越好 (4)离散度大(不同的值多)的列,放在联合索引前面。查看离散度,通过统计不同的列值来实现,count越大,离散程度越高: mysql> SELECT COUNT(DISTINCT column_name) FROM table_name;

MySQL 架构与历史

和自甴很熟 提交于 2020-02-27 08:35:33
1、MySQL 逻辑架构,上层客户端-----》连接/线程处理------》解析器-----》优化器 -----》存储引擎,解析器如果有生成查询缓存,那么连接/线程处理也有可能直接到查询缓存,返回结果,图如下 2、并发控制,读写锁,共享锁,排他锁,锁粒度(表锁 table lock 行级锁 row lock) 3、事务 :原子性,一致性,隔离性,持久性 隔离级别:未提交度,提交读(不可重复读),可重复读 ,可串行化 死锁 MySQL 中的事务 4、多版本并发控制(MVCC),只在REPEATABLE READ 和 READ COMMIT下工作,原理就是每行记录后面加两个隐藏的列来实现,一个保存行的创建时间,一个保存行的过期时间;这个时间是指系统版本号; 4、MySQL存储引擎 InnoDB MyISAM archive(只支持isert和select操作,日志或者数据采集类) CSV fedetated引擎 Memory引擎(HEAP表)临时表局势memory引擎,场景 NDB集群引擎 第三方存储引擎(OLTP类引擎,XtrDB PBXT TokuDB) 面向列的存储引擎 infobright,大数据量 如何转换表引擎? 1、ALTER TABLE 慢,会消耗系统所有的I/O能力 2、导入与导出 3、创建与查询 create table innodb_table like

Limit参数优化MySQL查询的方法

主宰稳场 提交于 2020-02-27 08:35:09
在做一些查询时,总希望能避免数据库引擎做全表扫描,因为全表扫描时间长,而且其中大部分扫描对客户端而言是没有意义的。 那么,在 mysql 中有那些方式是可以避免全表扫面?除了通过使用索引列或分区等方式来进行查询的优化之外,还有那些呢? 看了一个老外写的程序,在 MySQL 查询中使用了很多 Limit 关键字,这就让我很感兴趣了,因为在我印象中, Limit 关键字似乎更多被使用 MySQL 数据库的程序员用来做查询分页(当然这也是一种很好的查询优化),那在这里举个例子,假设我们需要一个分页的查询 ,Oracle中一般来说都是用以下 SQL 句子实现: SELECT * FROM ( SELECT a1.*, rownum rownum_ FROM testtable a1 WHERE rownum > 20) WHERE rownum_ <= 1000 此语句能查询到 testtable 表中的 20 到 1000 记录,而且还需要嵌套查询,效率不会太高,看看 MySQL 的实现: SELECT * FROM testtable a1 limit 20,980; 这样就能返回 testtable 表中的 21 条到( 20 + 980 =) 1000 条的记录。 实现语法确实简单,但如果要说这里两个 SQL 语句的效率,那就很难做比较了,因为在 MySQL 中 Limit

Mysql Join语句执行流程

荒凉一梦 提交于 2020-02-27 07:30:05
今天我们来看一下join语句的执行流程 JOIN主要使用 Index Nested-Loop Join 和 Block Nested-Loop Join 算法实现 Index Nested-Loop Join 如果 join on 相关的字段存在索引就使用 Index Nested-Loop Join 算法来进行关联 如下sql语句的执行过程: select * from t1 join t2 on (t1.a=t2.a); 对驱动表 t1 做了全表扫描,这个过程需要扫描 100 行; 而对于每一行 R,根据 a 字段去表 t2 查找,走的是树搜索过程。由于我们构造的数据 都是一一对应的,因此每次的搜索过程都只扫描一行,也是总共扫描 100 行; 所以,整个执行流程,总扫描行数是 200。 假设不使用 join,那我们就只能用单表查询。我们看看上面这条语句的需求,用单表查询 怎么实现。 执行select * from t1,查出表 t1 的所有数据,这里有 100 行; 循环遍历这 100 行数据: 从每一行 R 取出字段 a 的值 $R.a; 执行select * from t2 where a=$R.a; 把返回的结果和 R 构成结果集的一行。 可以看到,在这个查询过程,也是扫描了 200 行,但是总共执行了 101 条语句,比直接 join 多了 100 次交互。除此之外

MySQL的视图、事务和索引

陌路散爱 提交于 2020-02-27 05:02:56
视图 1. 为什么要有视图 对于复杂的查询,往往是有多个数据表进行关联查询而得到,如果数据库因为需求等原因发生了改变,为了保证查询出来的数据与之前相同,则需要在多个地方进行修改,维护起来非常麻烦 解决办法:定义视图 2. 视图是什么 通俗的讲,视图就是一条SELECT语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。 视图是对若干张基本表的引用,一张虚表,查询语句执行的结果,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变); 方便操作,特别是查询操作,减少复杂的SQL语句,增强可读性; 3. 定义视图 建议以v_开头 create view 视图名称 as select语句; 4. 查看视图 查看表会将所有的视图也列出来 show tables; 5. 使用视图 视图的用途就是查询 select * from v_stu_score; 6. 删除视图 drop view 视图名称; 例: drop view v_stu_sco; 8. 视图的作用 提高了重用性,就像一个函数 对数据库重构,却不影响程序的运行 提高了安全性能,可以对不同的用户 让数据更加清晰 事务 1. 为什么要有事务 事务广泛的运用于订单系统、银行系统等多种场景 例如: A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事: 检查A的账户余额

MySQL之数据库优化

人走茶凉 提交于 2020-02-27 04:39:10
Mysql数据库的优化技术 对mysql优化是一个综合性的技术,主要包括 •表的设计合理化(符合3NF) •添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引] •分表技术(水平分割、垂直分割) •读写[写: update/delete/add]分离 •存储过程 [模块化编程,可以提高速度] •对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ] •mysql服务器硬件升级 •定时的去清除不需要的数据,定时进行碎片整理(MyISAM) 数据库优化工作 对于一个以数据为中心的应用,数据库的好坏直接影响到程序的性能,因此数据库性能至关重要。一般来说,要保证数据库的效率,要做好以下四个方面的工作: ① 数据库设计 ② sql语句优化 ③ 数据库参数配置 ④ 恰当的硬件资源和操作系统 此外,使用适当的存储过程,也能提升性能。 这个顺序也表现了这四个工作对性能影响的大小 数据库表设计 通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通 俗地理解是够用的理解,并不是最科学最准确的理解): 第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足1NF) 第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

阅读记录(持续更新)

我是研究僧i 提交于 2020-02-27 01:22:32
坚持阅读,温故知新~^o^~ 电子书: http://www.sqlservercentral.com/books/ 、 http://www.red-gate.com/learning-community/community/books/ 2019年11月 1、《千金良方——MySQL性能优化金字塔法则》 2、《深入浅出MySQL 数据库开发、优化与管理维护(第3版)》 <!--正在阅读的图书--> <div id="reading-book"> <p>正在阅读的<a href="http://www.cnblogs.com/Uest/p/6123775.html" target="_blank" title="查看阅读记录">图书</a>:</p> <p> <a href="https://item.jd.com/12728070.html" target="_blank"> <img style="width: 117px; height: 135px;" src="https://files-cdn.cnblogs.com/files/Uest/Books-MySQLPerformanceOptimization.gif" title="千金良方——MySQL性能优化金字塔法则"> </a> <a href="https://item.jd.com/12574719

MySQL之LEFT JOIN问题汇总

情到浓时终转凉″ 提交于 2020-02-26 21:55:25
使用ON和WHRERE对表数据过滤 背景 left join在我们使用mysql查询的过程中可谓非常常见,比如博客里一篇文章有多少条评论、商城里一个货物有多少评论、一条评论有多少个赞等等。但是由于对join、on、where等关键字的不熟悉,有时候会导致查询结果与预期不符,所以今天我就来总结一下,一起避坑。 这里我先给出一个场景,并抛出两个问题,如果你都能答对那这篇文章就不用看了。 假设有一个班级管理应用,有一个表classes,存了所有的班级;有一个表students,存了所有的学生,具体数据如下(在线SQL: https://www.liaoxuefeng.com/wiki/1177760294764384/1179611432985088): SELECT * FROM classes; id name 1 一班 2 二班 3 三班 4 四班 SELECT * FROM students; id class_id name gender 1 1 小明 M 2 1 小红 F 3 1 小军 M 4 1 小米 F 5 2 小白 F 6 2 小兵 M 7 2 小林 M 8 3 小新 F 9 3 小王 M 10 3 小丽 F 那么现在有两个需求: 1、找出每个班级的名称及其对应的女同学数量 2、找出一班的同学总数 对于需求1,大多数人不假思索就能想出如下两种sql写法,请问哪种是对的?

查询内存溢出

人走茶凉 提交于 2020-02-26 21:33:30
首先我们来看一个带排序的查询,点击工具栏的 显示包含实际的执行计划。 1 SELECT * FROM AdventureWorks2008R2.Person.Person WHERE FirstName LIKE 'w%' ORDER BY 1 从执行计划里可以看出,SELECT运算符包含了 内存授予(Memory Grant) 信息(一般情况下不会出现,这里是因为我们的语句包含排序操作)。内存授予是KB为单位,是当执行计划中的一些运算符(像Sort/Hash等运算符)的执行,需要使用内存来完成——因此也被称为 查询内存(Query Memory) 。 在查询正式执行前,查询内存必须被SQL Server授予才可以。对于提供的查询,查询优化器根据查询对象的对应统计信息来决定需要多少查询内存。现在的问题就是,当统计信息过期了,SQL Server就会低估要处理的行数。在这个情况下,SQL Server对于提供的查询还是会请求更少的查询内存。但当查询真正开始后,SQL Server就不能改变授予的内存大小,也不能请求更多的内存。查询必须在授予的查询内存里完成操作。在这个情况下,SQL Server需要把Sort/Hash运算符涌进TempDb,这就意味我们原先在内存里快速操作变成物理磁盘上慢速操作。SQL Server Profiler可以通过 Sort Warnings 和 Hash

MySql查询语法实现细节

北城以北 提交于 2020-02-26 20:57:50
MySql查询语法揭秘 作为一名后端开发人员, 数据库可谓是与你如影随形, 但是天天和数据库打交道的你真的了解数据库么, 你写的每一条查询语句内部是怎么工作的你有没有了解过呢, 或许大多数的人只是停留在会用的阶段, 并不了解其实现细节. 如果SQL查询语句的实现细节不了解的话, 那么优化也无从说起, 所以下面就聊聊sql的查询细节. 1. Mysql查询语法书写顺序 SELECT FROM LEFT JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT 2. Mysql查询语句执行细节 示例SQL语句 select * from user left join order on user.id = order.uid where order.price > 1000 group by user.name having count(1) > 5 order by user.name limit 0, 10; 注 : select * 会影响查询效率, 这里只是方便举例子 FROM(将最近的两张表,进行笛卡尔积) —VT1 ON(将VT1按照它的条件进行过滤) —VT2 LEFT JOIN(保留左表的记录) —VT3 WHERE(过滤VT3中的记录) --VT4…VTn GROUP BY(对VT4的记录进行分组) —VT5 HAVING