mysql创建索引

mysql 实战 or、in与union all 的查询效率

断了今生、忘了曾经 提交于 2019-11-29 08:23:45
OR、in和union all 查询效率到底哪个快。 网上很多的声音都是说union all 快于 or、in,因为or、in会导致全表扫描,他们给出了很多的实例。 但真的union all真的快于or、in?本文就是采用实际的实例来探讨到底是它们之间的效率。 1:创建表,插入数据、数据量为1千万【要不效果不明显】。 Sql代码 drop table if EXISTS BT; create table BT( ID int (10) NOT NUll , VName varchar (20) DEFAULT '' NOT NULL , PRIMARY key ( ID ) )ENGINE=INNODB; 该表只有两个字段 ID为主键【索引页类似】,一个是普通的字段。(偷懒就用简单的表结构呢) 向BT表中插入1千万条数据 这里我写了一个简单的存储过程【所以你的mysql版本至少大于5.0,俺的版本为5.1】,代码如下。 注意:最好 INSERT INTO BT ( ID,VNAME ) VALUES( i, CONCAT( 'M', i ) );---1 修改为 INSERT INTO BT ( ID,VNAME ) VALUES( i, CONCAT( 'M', i, 'TT' ) );---2 修改原因在 非索引列及VNAME使用了联合进行完全扫描请使用1 。

MySQL Order By索引优化

十年热恋 提交于 2019-11-29 08:20:27
在一些情况下,MySQL可以直接使用索引来满足一个 ORDER BY 或 GROUP BY 子句而无需做额外的排序。尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了。 使用索引的MySQL Order By 下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2; SELECT * FROM t1 WHERE key_part1=constant GROUP BY key_part2; SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC; SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2 DESC; 不使用索引的MySQL Order By 在另一些情况下,MySQL无法使用索引来满足 ORDER BY,尽管它会使用索引来找到记录来匹配 WHERE 子句。这些情况如下: *

mysql知识点汇总

佐手、 提交于 2019-11-29 08:20:08
1. 数据库的安装 2. 数据库设计需要注意什么 3. SQL语句优化 4. 怎样处理慢查询? 5. 怎样更好的利用数据库索引? 6. 事务隔离级别有哪些?怎么实现的? 7. 数据库锁有哪些? 8. 如何保证数据库高可用? 9. 如何保证数据库高并发? 10. 什么样的数据库缓存方案最合理? 11. innodb和myisam对比 12. 有哪些好用的数据库中间件? 13. 数据库日志介绍 14. 数据库主从复制 mysql 数据主从的实现方式:RBR,SBR,MBR 2. 索引: B+Tree 1)一个节点存储多个数据,这样的好处,是可以充分利用预读功能。 2)节点上是不存储数据的(这里是指不存储指向数据真实地址的指针或主键地址),所有的数据都在叶子节点上。并且每个叶子节点有一个指向下一个叶子节点的指针,这样可以方便遍历。 索引分类: B-Tree索引: 哈希索引(hash index):哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效。结构十分紧凑,查询速度非常快。 空间数据索引: 全文索引: innodb索引分类: 聚簇索引(clustered index):1) 有主键时,根据主键创建聚簇索引; 2) 没有主键时,会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引; 3) 如果以上两个都不满足那innodb自己创建一个虚拟的聚集索引 辅助索引

MySQL各类SQL语句的加锁机制

做~自己de王妃 提交于 2019-11-29 08:19:27
官网参考: https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html MySQL把读操作分为两大类:锁定读和非锁定读(即locking read和nonlocking read),所谓非锁定读就是不对表添加事务锁的读操作,如Repeatable Read和Read Committed隔离级别下的select语句(可能脏读也算?)。MySQL的一致性非锁定读是通过MVCC机制实现的。锁定读是指添加事务锁的读操作,例如select for update和select lock in share mode语句。 关于MySQL的锁机制和事务隔离级别,参考以下两篇博客: http://www.cnblogs.com/leohahah/p/8862216.html http://www.cnblogs.com/leohahah/p/8857124.html 第一部分:概述 锁定读、update和delete,这些操作通常会在扫描到的索引记录上添加record locks,InnoDB不关心这些行是否会被where条件过滤,因为InnoDB不记得具体的where条件,它只知道哪个索引范围被扫描过。 这些锁定添加的锁通常是next-key lock,这种锁既锁定扫描到的索引记录,也锁定索引间的gap。不过gap锁可以被显示的禁用

MySQL认识索引

老子叫甜甜 提交于 2019-11-29 08:16:46
MySQL认识索引 什么是索引? 索引在MySQL中也叫是一种“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能 非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。 索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。 索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。 索引的原理 索引原理 索引的目的在于提高查询效率,与我们查阅图书所用的目录是一个道理:先定位到章,然后定位到该章下的一个小节,然后找到页数。相似的例子还有:查字典,查火车车次,飞机航班等 本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。 数据库也是一样,但显然要复杂的多,因为不仅面临着等值查询,还有范围查询(>、<、between、in)、模糊查询(like)、并集查询(or)等等。数据库应该选择怎么样的方式来应对所有的问题呢?我们回想字典的例子,能不能把数据分成段,然后分段查询呢?最简单的如果1000条数据,1到100分成第一段,101到200分成第二段,201到300分成第三段......这样查第250条数据,只要找第三段就可以了,一下子去除了90%的无效数据。但如果是1千万的记录呢

MySQL锁机制

为君一笑 提交于 2019-11-29 08:16:05
本文参考自MySQL官网5.6版本参考手册的14.5.1,此小节说明MySQL的锁分类,此外还有14.5.2小节和14.5.3小节详述事务隔离级别和各SQL语句的加锁模式,后两节将单独写2篇笔记。 https://dev.mysql.com/doc/refman/5.6/en/innodb-locking.html https://dev.mysql.com/doc/refman/5.6/en/innodb-transaction-isolation-levels.html https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_rw_lock MySQL各类SQL语句的加锁机制 MySQL事务隔离级别 第一部分:概述 Myisam的锁比较容易理解,无论是读还是写都只会加表锁,表锁又分为read锁和write锁,可以使用如下方式手动加锁: --加表锁语句(同样适用于InnoDB): lock tables tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ... lock_type: READ [LOCAL] |

Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)

放肆的年华 提交于 2019-11-29 08:15:48
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响 Mysql加锁过程详解(5)-innodb 多版本并发控制原理详解 Mysql加锁过程详解(6)-数据库隔离级别(1) Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别 Mysql加锁过程详解(7)-初步理解MySQL的gap锁 Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock) Record lock 单条索引记录上加锁, record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引 ,那么锁住的就是这个隐藏的聚集主键索引。 所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁 ,但原理上和表锁应该是完全不同的。 Gap lock 在索引记录之间的间隙中加锁 ,或者是在某一条索引记录之前或者之后加锁, 并不包括该索引记录本身 。gap lock的机制主要是解决可重复读模式下的幻读问题,关于幻读的演示和gap锁如何解决了幻读

MySQL InnoDB事务,锁机制

大兔子大兔子 提交于 2019-11-29 08:13:03
MVCC:Snapshot Read vs Current Read MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC ( Multi-Version Concurrency Control ) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC最大的好处,相信也是耳熟能详:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,这也是为什么现阶段,几乎所有的RDBMS,都支持了MVCC。 在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。 Innodb锁问题 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题。下面我们先介绍一点背景知识,然后详细讨论InnoDB的锁问题。 InnoDB实现了以下两种类型的行锁。 l 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

mysql InnoDB加锁分析

一笑奈何 提交于 2019-11-29 08:12:52
文章转载自: http://www.fanyilun.me/2017/04/20/MySQL%E5%8A%A0%E9%94%81%E5%88%86%E6%9E%90/ 以下实验数据基于MySQL 5.7。 假设已知一张表my_table,id列为主键 id name num 1 aaa 100 5 bbb 200 8 bbb 300 10 ccc 400 1. 查询命中聚簇索引(主键索引) 1.1 如果是精确查询,那么会在命中的索引上加record lock // 在id=1的聚簇索引上加X锁 update my_table set name='a' where id=1; // 在id=1的聚簇索引上加S锁 select * from my_table where id=1 lock in share mode; 1.2 如果是范围查询,那么 1.2.1 在RC隔离级别下,会在所有命中的行的聚簇索引上加record locks(只锁行) // 在id=8和10的聚簇索引上加X锁 update my_table set name='a' where id>7; // 在id=1的聚簇索引上加X锁 update my_table set name='a' where id<=1; 1.2.2 在RR隔离级别下,会在所有命中的行的聚簇索引上加next-key locks(锁住行和间隙)

写给 Java 程序员的 24 个MySQL面试题,拿走不谢!

核能气质少年 提交于 2019-11-29 08:09:48
一、为什么用自增列作为主键?   1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引。   如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引。   如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。   2、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上,这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放   因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)   3、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页   4、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置   此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销   同时频繁的移动、分页操作造成了大量的碎片