sql优化

神奇的 SQL 之 ICP → 索引条件下推

廉价感情. 提交于 2020-03-09 10:03:51
开心一刻   楼主:来,我们先排练一遍   小伙伴们:好   嘿、哈、嚯   楼主:非常好,就是这个节奏,我们开始吧   楼主:啊、啊、啊,疼 ! 你们是不是故意的 ? 回表与覆盖索引   正式讲 ICP 之前了,我们先将相关的概念捋一捋,知道的就当回顾,不知道的就当了解了,这有助于对 ICP 的理解   建个示例表 tbl_index CREATE TABLE tbl_index ( c1 INT, c2 INT, c3 CHAR(1), PRIMARY KEY(c1), KEY idx_c2 (c2) );   覆盖索引     如果 where 条件的列和 select 的列都在一个索引中,通过这个索引就可以完成查询,这就叫就叫覆盖索引;当然,覆盖索引基本针对的是组合索引(InnoDB 的聚簇索引有点特殊,具体可以看下面的图)     针对上面的 tbl_index, select c2 from tbl_index where c2 = 4 ; 是覆盖索引查询,但是这条 SQL 没有意义,如果我们在 tbl_index 表上增加索引 index idx_c2_c3 (c2,c3) ,那么 select c3 from tbl_index where c2 = 4 ; 走覆盖索引查询还是很有意义的,那问题又来了,覆盖索引的意义何在 ? 我们往下看   回表    

MySQL事务的实现原理

扶醉桌前 提交于 2020-03-09 08:47:27
天天用事务,但是你知道MySQL事务的实现原理吗? 1. 开篇 相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durability)等。今天想跟大家一起研究下事务内部到底是怎么实现的,在讲解前我想先抛出个问题: 事务想要做到什么效果? 按我理解,无非是要做到可靠性以及并发处理。 可靠性:数据库要保证当insert或update操作时抛异常或者数据库crash的时候需要保障数据的操作前后的一致,想要做到这个,我需要知道我修改之前和修改之后的状态,所以就有了undo log和redo log。 并发处理:也就是说当多个并发请求过来,并且其中有一个请求是对数据修改操作的时候会有影响,为了避免读到脏数据,所以需要对事务之间的读写进行隔离,至于隔离到啥程度得看业务系统的场景了,实现这个就得用MySQL 的隔离级别。 下面我首先讲实现事务功能的三个技术,分别是日志文件(redo log 和 undo log),锁技术以及MVCC,然后再讲事务的实现原理,包括原子性是怎么实现的,隔离型是怎么实现的等等。最后在做一个总结,希望大家能够耐心看完 redo log与undo log介绍 mysql锁技术以及MVCC基础 事务的实现原理 总结 2 redo log 与 undo log介绍 1. redo

sql server 索引阐述系列七 索引填充因子与碎片

拥有回忆 提交于 2020-03-09 04:24:37
原文: sql server 索引阐述系列七 索引填充因子与碎片 一.概述     索引填充因子作用: 提供填充因子选项是为了优化索引数据存储和性能。 当创建或重新生成索引时,填充因子的值可确定每个叶级页上要填充数据的空间百分比,以便在每一页上保留一些剩余存储空间作为以后扩展索引的可用空间,例如:指定填充因子的值为 80 表示每个叶级页上将有 20% 的空间保留为空,以便随着向基础表中添加数据而为扩展索引提供空间。   填充因子的值是 1 到 100 之间的百分比,服务器范围的默认值为 0,这表示将完全填充叶级页。  1.1 页拆分现象    根据数据的查询和修改的比例, 正确选择填充因子值,可提供足够的空间,以便随着向基础表中添加数据而扩展索引,从而降低页拆分的可能性。如果向已满的索引页添加新行(新行位置根据键排序规则,可以是页中任意行位置), 数据库引擎将把大约一半的行移到新页中,以便为该新行腾出空间。 这种重组称为页拆分。 页拆分可为新记录腾出空间,但是执行页拆分可能需要花费一定的时间,此操作会消耗大量资源。 此外,它还可能造成碎片,从而导致 I/O 操作增加。 如果经常发生页拆分(可能过sys.dm_db_index_physical_stats 来查看页拆分情况),可通过使用新的或现有的填充因子值来重新生成索引,从而重新分发数据。   填充值设置过低: 优点是

sql server 索引阐述系列七 索引填充因子与碎片

给你一囗甜甜゛ 提交于 2020-03-09 04:22:42
一.概述     索引填充因子作用: 提供填充因子选项是为了优化索引数据存储和性能。 当创建或重新生成索引时,填充因子的值可确定每个叶级页上要填充数据的空间百分比,以便在每一页上保留一些剩余存储空间作为以后扩展索引的可用空间,例如:指定填充因子的值为 80 表示每个叶级页上将有 20% 的空间保留为空,以便随着向基础表中添加数据而为扩展索引提供空间。   填充因子的值是 1 到 100 之间的百分比,服务器范围的默认值为 0,这表示将完全填充叶级页。  1.1 页拆分现象    根据数据的查询和修改的比例, 正确选择填充因子值,可提供足够的空间,以便随着向基础表中添加数据而扩展索引,从而降低页拆分的可能性。如果向已满的索引页添加新行(新行位置根据键排序规则,可以是页中任意行位置), 数据库引擎将把大约一半的行移到新页中,以便为该新行腾出空间。 这种重组称为页拆分。 页拆分可为新记录腾出空间,但是执行页拆分可能需要花费一定的时间,此操作会消耗大量资源。 此外,它还可能造成碎片,从而导致 I/O 操作增加。 如果经常发生页拆分(可能过sys.dm_db_index_physical_stats 来查看页拆分情况),可通过使用新的或现有的填充因子值来重新生成索引,从而重新分发数据。   填充值设置过低: 优点是 插入或修改时降低页的拆分次数。缺点是 会使索引需要更多的存储空间

高性能MySQL 第六章

浪尽此生 提交于 2020-03-08 20:25:18
查询优化、索引优化、库表结构优化需要齐头并进,一个不落,才能最终设计出在实际场景中能发挥良好效果的方案。 为什么查询速度会慢? 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上要优化其子任务,要么雄楚其中一些子任务,要么减少子任务的执行次数,要么让任务运行得更快。 如何优化数据访问? 1、确认是否向数据库请求了不需要的数据 2、确认 MySQL 是否在扫描额外的记录 3、确认查询的方式,并予以合适的重构 当希望 MySQL 能够以更高的性能运行查询时,最好的办法就是弄清楚 MySQL 是如何优化和执行查询的。一旦理解这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理的方式运行。 那么,当 MySQL 执行一个查询时,MySQL 到底做了什么? 1、客户端发送一条查询给服务器 2、服务器先检查查询缓存,如果命中了魂村,则立刻返回存储在魂村中的结果。否则进入下一阶段。 3、服务器端进行 SQL 解析、预处理,再由优化器生成对应的执行计划 4、MySQL 根据优化器生成的执行计划,条用存储引擎的 API 来执行查询 5、将结果返回给客户端 来源: https://www.cnblogs.com/stone94/p/12444491.html

共享池中保留池的调整(shared_pool_reserved_size)

为君一笑 提交于 2020-03-08 18:28:31
--************************************************* -- 共享池中保留池的 调 整 (shared_pool_reserved_size) --************************************************* 1 . 何 谓 保留池 简 言之,保留一部分 内 存空 间 以 备 不 时 之需。通常情 况 下, Oracle 会将 大的 内 存 请 求分割成小的 内 存 块来满 足需求。而 对 于大的 内 存且 为连续 的 内 存空 间请 求,如果在共享池中未找到, 则会动 用 共享池中的保留池。 当 然,共享池在 内 存 压 力的情 况 下,也 会 使用到 保留池中的部分。保留池部分 满 足 较 大的 内 存需求更高效。缺省情 况 下, Oracle 会 配置 较 小的保留池, 这 部分可以用作 PL/SQL 或 触发 器 编译 使用或用于装 载 JAVA 对 象的 临时 空 间 。 这 些分配出去的 内 存一旦 释 放后 将 返回 给 保留池。 任意大于 "_shared_pool_reserved_min_alloc = 4400" 字 节 的 连续内 存分配 请 求,如果 shared_pool 中分配不能解 决 ,且 当 前 shared_pool 中 没 有可用的 块 能 够 aged

MySQL中的基本SQL语句

余生长醉 提交于 2020-03-08 18:15:45
标准SQL包含了4种基本的语句类别: DDL语句,数据定义语句,主要用来定义数据库,表名,字段,例如create,drop,alter. DML语句,数据操作语句,用来对数据记录的增删改查,还用来保证数据的一致性。主要有select,delete,insert,update语句。 DCL语句,数据控制语句,用于控制不同数据对象访问级别的语句。定义了数据库、表、表、用户的访问权限和完全级别。常用的语句包括grant、revoke等 TCL语句,事务控制语句,用来确保事务的特性。 CREATE TABLE建表语句 在介绍建表语句之前,先简单说明一下创建数据库的语句。 mysql> create database mytest; #创建数据库 Query OK, 1 row affected (0.00 sec) mysql> use mytest; #改变当前的数据库 Database changed mysql> select database(); #查看当前选中的数据库 +------------+ | database() | +------------+ | mytest | +------------+ 1 row in set (0.00 sec) mysql> select user(); #查看当前登录的用户 +----------------+ | user() |

2. 影响mysql性能的因素

我的梦境 提交于 2020-03-08 17:32:57
影响mysql性能的几个方面: 1. 服务器硬件 2. 服务器操作系统 3. 数据库存储引擎 4. 数据库参数配置 5. 数据库结构设计和SQL语句 服务器硬件: 1. CPU: CPU密集型的应用,应选用频率更高的CPU而不是更多的CPU WEB类的应用,CPU核心数量比频率重要 2. 内存: 内存越多越好,内存对读、写都有作用 内存频率越高速度越快,应选择主板支持的最大内存频率,单条容量尽可能大 3. 磁盘: 传统机器硬盘:1.存储容量 2.传输速度 3.访问时间 4.主轴转速 5.物理尺寸 RAID(磁盘冗余阵列): 1.RAID 0,2块以上的硬盘组成,没有冗余和错误修复能力 2.RAID 1,磁盘镜像,2块硬盘组成,有冗余 3.RAID 5,分布式奇偶性校验阵列,3块以上的硬盘组成,任意一个盘数据失效时可以重建,更多盘数据失效时无法重建 4.RAID 10,分片镜像,RAID 0和RAID 1组合,4块以上的硬盘组成,对比RAID 5重建更简单,速度更快 固态存储SSD或PCI-E卡: 比机械硬盘有更好的随机读写性能 比机械硬盘能更好的支持并发 比机械硬盘更容易损坏 适用于存在大量随机I/O的场景 适用于解决单线程负载的I/O瓶颈 网络存储SAN和NAS: SAN的随机读写慢,不如本地RAID磁盘 NAS设备使用网络连接,通过基于文件的协议如NFS或SMB来访问

高性能MySQL之基础架构

喜欢而已 提交于 2020-03-08 12:22:45
原文: 高性能MySQL之基础架构 一、背景 当你手中抓住一件东西不放时,你只能拥有一件东西,如果你肯放手,你就有机会选择更多。与其在别人的生活里跑龙套,不如精彩做自己。人无所舍,必无所成。跌倒了,失去了,不要紧,爬起来继续风雨兼程,且歌且行。 为什么我们需要先学习MYSQL的基础架构先呢? 原因很简单,当我们需要了解一件事物的时候,我们只有站在宏观的层面,才能层层剥丝抽茧的去理解问题。举个例子,我们要看一个框架的源码,一开始就想进去研究,却发现找不着北,原因很简单,因为我们没有鸟瞰全貌,我们根本不知道入口在哪里。因此我们学习MYSQL的时候也是这样。先从高纬度理解问题,最后看到里面有哪些组件,一层层的拆解,这样让我们对mysql有更深入的理解。废话不多说,我们先看总体的逻辑架构图,如下所示。 二、Mysql总体逻辑架构 从图中不难看出,不同的存储引擎共用一个Server层,也就是从连接器到执行器的部分。可以看到Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如触发器、视图等。 需要主意的是存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB

mysql 操作总结 INSERT和REPLACE

若如初见. 提交于 2020-03-08 11:42:08
--他人总结的 用于操作数据库的SQL一般分为两种,一种是查询语句,也就是我们所说的SELECT语句,另外一种就是更新语句,也叫做数据操作语句。 言外之意,就是对数据进行修改。在标准的SQL中有3个语句,它们是INSERT、UPDATE以及DELETE。在MySQL中又多了一个REPLACE语句,因此,本文以MySQL为背景来讨论如何使有SQL中的更新语句。   一、INSERT和REPLACE   INSERT和REPLACE语句的功能都是向表中插入新的数据。这两条语句的语法类似。它们的主要区别是如何处理重复的数据。   1. INSERT的一般用法   MySQL中的INSERT语句和标准的INSERT不太一样,在标准的SQL语句中,一次插入一条记录的INSERT语句只有一种形式。   INSERT INTO tablename(列名…) VALUES(列值);   而在MySQL中还有另外一种形式。   INSERT INTO tablename SET column_name1 = value1, column_name2 = value2,…;   第一种方法将列名和列值分开了,在使用时,列名必须和列值的数一致。如下面的语句向users表中插入了一条记录:   INSERT INTO users(id, name, age) VALUES(123, '姚明', 25);