索引

MySQL 性能调优之查询优化

烈酒焚心 提交于 2020-01-26 14:12:13
性能调优相关文档书籍 http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html 《MySQL性能调优与架构设计》 SQL查询优化总结 缺失索引,查询速度差别是100倍:首先应考虑在 where 及 order by 涉及的列上建立索引 1 show index from mb_ransomrequestform; 2 ALTER TABLE mb_ransomrequestform ADD INDEX IDX_corporationid (corporationid); 3 drop index IDX_corporationid on mb_ransomrequestform; View Code 避免在 where 子句使用不能使用索引的操作符,比如!=、<>、like “%xx%”、or。否则将导致引擎放弃使用索引而进行全表扫描。 1)like “%xx%”改成like “xxx%”可以使用索引 mysql> select bill.billId from EE_PawnBill bill, EE_PawnerInfo pawner where bill.pawnerid

Mysql 层级、执行顺序、执行计划分析

一笑奈何 提交于 2020-01-26 13:25:04
逻辑分层 下面是MySQL的逻辑分层图: 连接层:连接与线程处理,这一层并不是MySQL独有,一般的基于C/S架构的都有类似组件,比如连接处理、授权认证、安全等。 服务层:包括缓存查询、解析器、优化器,这一部分是MySQL核心功能,包括解析、优化SQL语句,查询缓存目录,内置函数(日期、时间、加密等函数)的实现。 引擎层:负责数据存储,存储引擎的不同,存储方式、数据格式、提取方式等都不相同,这一部分也是很大影响数据存储与提取的性能的;对存储层的抽象。 存储层:存储数据,文件系统。 存储引擎 查看数据库支持的存储引擎:show engines; 如果要想查看数据库默认使用哪个引擎,可以通过使用命令: show variables like '%storage_engine%'; InnoDB,MyISAM的主要区别: InnoDB:在MySQL5.5开始作为默认的存储引擎,支持事务,行级锁,适合高并发场景,XA协议支持分布式事务, 事务优先 。 MyISAM:不支持事务, 性能优先 ,表级锁,不适合高并发场景。 sql执行顺序: https://www.cnblogs.com/annsshadow/p/5037667.html explain-执行计划 explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 使用方法

一次浴火重生的MySQL优化(EXPLAIN命令详解)

给你一囗甜甜゛ 提交于 2020-01-26 13:21:21
一直对SQL优化的技能心存无限的向往,之前面试的时候有很多面试官都会来一句,你会优化吗?我说我不太会,这时可能很多人就会有点儿说法了,比如会说不要使用通配符*去检索表、给常常使用的列建立索引、还有创建表的时候注意选择更优的数据类型去存储数据等等,我只能说那些都是常识,作为开发人员是必须要知道的。但真正的优化并不是使用那些简单的手法去完成实现的,要想知道一条SQL语句执行效率低的原因,我们可以借助MySQL的一大神器---"EXPLAIN命令",EXPLAIN命令是查询性能优化不可缺少的一部分,本文在结合实例的同时会总结explain命令的使用及相关参数的说明。 首先说说我这次浴火重生的优化初衷吧,上个月在公司完成的统计模块中,其中就有几条SQL语句执行的速度稍微有点慢,心里一直留了一道坎。直到昨天晚上在家看了一篇文章,是关于MySQL优化的对EXPLAIN命令的详解,所以今天一到公司就想着把之前那些SQL语句的病赶紧给看看,虽然,我没有达到那种秒查的效果,但是优化的效果还是有明显的提升。 业务场景: 分区 统计XXX省 每月 上传数据的企业数量,何为企业是否是未上传数据,即专门存放上传数据的数据表中没有记录的为未上传数据的企业,如果有那么代表已经上传数据。 下面是我之前写的SQL语句(未优化前的),它执行的时间是 2.318sec ,并且使用EXPLAIN命令进行分析:

MySQL5.6之use_index_extensions优化

牧云@^-^@ 提交于 2020-01-26 12:54:55
InnoDB的二级索引(Secondary Index)除了存储索引列key值,还存储着主键值(而不是指向主键的指针)。为什么这样做?因为InnoDB是以聚集索引方式组织数据的存储,即主键值相邻的数据行紧凑的存储在一起(索引组织表)。当数据行移动或者发生页分裂的时候,可以减少大量的二级索引维护工作。InnoDB移动行时,无需更新二级索引。 CREATE TABLE t1 ( i1 INT NOT NULL DEFAULT 0, i2 INT NOT NULL DEFAULT 0, d DATE DEFAULT NULL, PRIMARY KEY (i1, i2), INDEX k_d (d) ) ENGINE = InnoDB; 数据表t1的schema设计如上面所示。二级索引k_d(d)的元组在InnoDB内部实际被扩展成(d,i1,i2),即包含主键值。因此在设计主键的时候,常见的一条设计原则是要求主键字段尽量简单(整型数值,自增),以避免二级索引过大。在MySQL5.6.9之前,优化器在决定是否使用一个索引或者怎样使用一个索引的时候,并不考虑索引中扩展的主键列这一部分。而从MySQL5.6.9开始,优化器开始考虑使用扩展的主键列,这样可以产生更高效的执行计划和更好的性能。 优化器可以把扩展的二级索引用于ref,range,index_merge索引访问、松散索引扫描

【mysql】Innodb三大特性之insert buffer

旧城冷巷雨未停 提交于 2020-01-26 12:33:27
一、什么是insert buffer insert buffer是一种特殊的数据结构(B+ tree) 并不是缓存的一部分,而是物理页 , 当受影响的索引页不在buffer pool时 缓存 secondary index pages的变化, 当buffer page读入buffer pool时 ,进行合并操作,这些操作可以是 INSERT , UPDATE , or DELETE operations (DML) 最开始的时候只能是insert操作,所以叫做insert buffer,现在已经改叫做change buffer了 insert buffer 只适用于 non-unique secondary indexes 也就是说 只能用在非唯一的索引上 ,原因如下 1、primary key 是 按照递增的顺序进行插入的,异常插入聚族索引一般也顺序的,非随机IO 2 写唯一索引要检查记录是不是存在,所以在修改唯一索引之前,必须把修改的记录相关的索引页读出来才知道是不是唯一、这样Insert buffer就没意义了,要读出来(随机IO) 所以只对非唯一索引有效 二、insert buffer的原理 对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页,而是把若干对同一页面的更新缓存起来做,合并为一次性更新操 作, 减少IO,转随机IO为顺序IO

Elasticsearch系列---shard内部原理

别来无恙 提交于 2020-01-26 12:02:09
概要 本篇我们来看看shard内部的一些操作原理,了解一下人家是怎么玩的。 倒排索引 倒排索引的结构,是非常适合用来做搜索的,Elasticsearch会为索引的每个index为analyzed的字段建立倒排索引。 基本结构 倒排索引包含以下几个部分: 某个关键词的doc list 某个关键词的所有doc的数量IDF(inverse document frequency) 某个关键词在每个doc中出现的次数:TF(term frequency) 某个关键词在这个doc中的次序 每个doc的长度:length norm 某个关键词的所有doc的平均长度 记录这些信息,就是为了方便搜索的效率和_score分值的计算。 不可变性 倒排索引写入磁盘后就是不可变的,这样有几个好处: 不需要锁,如果不更新索引,不用担心锁的问题,可以支持较高的并发能力 如果cache内存足够,不更新索引的话,索引可以一直保存在os cache中,可以提升IO性能。 如果数据不变,filter cache会一直驻留在内存。 索引数据可以压缩,节省cpu和io开销。 doc底层原理 前面提到倒排索引是基于不可变模式设计的,但实际Elasticsearch源源不断地有新数据进来,那光是建立、删除倒排索引,岂不是非常忙? 如果真是不停地建立,删除倒排索引,那ES压力也太大了,肯定不是这么实现的

sql中的split函数的实现

自作多情 提交于 2020-01-26 04:43:12
--创建一个函数,函数中有两个参数 Create FUNCTION [dbo].[SplitToTable] ( @SplitString nvarchar(max),--输入的字符串 @Separator nvarchar(10)=' '--分割条件 ) --返回的数据为一个表 RETURNS @SplitStringsTable TABLE ( [id] int identity(1,1), [value] nvarchar(max) ) AS BEGIN DECLARE @CurrentIndex int;--当前索引 DECLARE @NextIndex int;--下一个索引 DECLARE @ReturnText nvarchar(max);--返回内容 SELECT @CurrentIndex=1;--设置当前索引初始值为1 --当当前索引小于字符串长度时,执行循环体 WHILE(@CurrentIndex<=len(@SplitString)) BEGIN --CHARINDEX函数返回字符或者字符串在另一个字符串中的起始位置。CHARINDEX函数调用方法如下: --CHARINDEX ( expression1 , expression2 [ , start_location ] ) -- Expression1是要到expression2中寻找的字符中

SQL 优化原则

流过昼夜 提交于 2020-01-26 01:55:44
   一、问题的提出  在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优 化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的 SQL语句,提高系统的可用性。   在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的 SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种 原则来删除索引,这有助于写出高性能的SQL语句。   二、SQL语句编写注意问题   下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。    1. IS NULL 与 IS NOT NULL    不能用null作索引

Index索引文件

流过昼夜 提交于 2020-01-26 00:57:24
1.IndexHeader头部,40字节,记录IndexFile的统计信息: begainTimestamp:该索引文件中包含消息的最小存储时间 endTimestamp:该索引文件中包含消息的最大存储时间 begainPhyoffset:该索引文件中包含消息的最大物理偏移量(commitlog文件偏移量) endPhyoffset:该索引文件中包含消息的最大物理偏移量(commitlog文件偏移量) hashslotCount:hashslot个数,并不是hash槽的个数,在这里意义不大 indexCount:Index条目列表当前已使用的个数,Index条目在Index条目列表中按顺序存储 2.Hash槽,一个IndexFile默认包含500万个Hash槽,每个Hash槽存储的是落在该Hash槽的hashcode最新的Index的索引 3.Index条目列表:默认一个索引文件包含2000万个条目,每一个Index条目结构如下 hashcode:key的hashcode phyoffset:消息对应的物理偏移量 timedif:该消息存储时间与第一条消息的时间戳的差值,小于0该消息无效 preIndexNo:该条目的前一条记录的Index索引,当出现hash冲突时,构建的链表结构 关键:map<String消息索引key,long 消息物理偏移量> IndexFile

底层源码分析 MySQL 死锁问题

☆樱花仙子☆ 提交于 2020-01-26 00:36:03
这篇文章主要讲的是如何通过调试 MySQL 源码,知道一条 SQL 真正会拿哪些锁,不再抓虾,瞎猜或者何登成大神没写过的场景就不知道如何处理了 通过好多个深夜艰难的单步调试,终于找到了一个理想的断点,可以看到大部分获取锁的过程 代码在 lock0lock.c 的 static enum db_err lock_rec_lock() 函数中,这个函数会显示,获取锁的过程,以及获取锁成功与否的情况 对于之前何登成大神博客里面的内容( hedengcheng.com/?p=771 ), 我们来做实验逐个验证(以下介绍的都是在 RC 隔离级别下的实验) 场景1:通过主键进行删除 表结构 CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB; delete from t1 where id = 10; 复制代码 可以看到,对索引 PRIMARY 加锁,mode = 1027,1027是什么意思呢?1027 = LOCK_REC_NOT_GAP + LOCK_X(非 gap 的记录锁且是 X 锁) 过程如下 结论:根据主键 id 去删除数据,且没有其它索引的情况下,此 SQL 只需要在