⑴ mysql怎么添加索引sql语句
工具:mysql数据库创建一个user的表里边的字段
1.普通索引 添加INDEX
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
下面演示下给user表的name字段添加一个索引
2.主键索引 添加PRIMARY KEY
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
3.唯一索引 添加UNIQUE
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
4.全文索引 添加FULLTEXT
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
5.如何添加多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
⑵ mysql 核心内容-上
1、SQL语句执行流程
MySQL大体上可分为Server层和存储引擎层两部分。
Server层:
连接器:TCP握手后服务器来验证登陆用户身份,A用户创建连接后,管理员对A用户权限修改了也不会影响到已经创建的链接权限,必须重新登陆。
查询缓存:查询后的结果存储位置,MySQL8.0版本以后已经取消,因为查询缓存失效太频繁,得不偿失。
分析器:根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。
优化器:多种执行策略可实现目标,系统自动选择最优进行执行。
执行器:判断是否有权限,将最终任务提交到存储引擎。
存储引擎层
负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始成为了默认存储引擎(经常用的也是这个)。
SQL执行顺序
2、BinLog、RedoLog、UndoLog
BinLog
BinLog是记录所有数据库表结构变更(例如create、alter table)以及表数据修改(insert、update、delete)的二进制日志,主从数据库同步用到的都是BinLog文件。BinLog日志文件有三种模式。
STATEMENT 模式
内容:binlog 记录可能引起数据变更的 sql 语句
优势:该模式下,因为没有记录实际的数据,所以日志量很少 IO 都消耗很低,性能是最优的
劣势:但有些操作并不是确定的,比如 uuid() 函数会随机产生唯一标识,当依赖 binlog 回放时,该操作生成的数据与原数据必然是不同的,此时可能造成无法预料的后果。
ROW 模式
内容:在该模式下,binlog 会记录每次操作的源数据与修改后的目标数据,StreamSets就要求该模式。
优势:可以绝对精准的还原,从而保证了数据的安全与可靠,并且复制和数据恢复过程可以是并发进行的
劣势:缺点在于 binlog 体积会非常大,同时,对于修改记录多、字段长度大的操作来说,记录时性能消耗会很严重。阅读的时候也需要特殊指令来进行读取数据。
MIXED 模式
内容:是对上述STATEMENT 跟 ROW 两种模式的混合使用。
细节:对于绝大部分操作,都是使用 STATEMENT 来进行 binlog 没有记录,只有以下操作使用 ROW 来实现:表的存储引擎为 NDB,使用了uuid() 等不确定函数,使用了 insert delay 语句,使用了临时表
主从同步流程:
1、主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
2、从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件 。
3、主节点启动一个线程(mp Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
4、从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置(主节点中的二进制文件会有多个)。
5、从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。
mysql默认的复制方式是异步的,并且复制的时候是有并行复制能力的。主库把日志发送给从库后不管了,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。
全同步复制
主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。
半同步复制
半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。
还可以延伸到由于主从配置不一样、主库大事务、从库压力过大、网络震荡等造成主备延迟,如何避免这个问题?主备切换的时候用可靠性优先原则还是可用性优先原则?如何判断主库Crash了?互为主备的情况下如何避免主备循环复制?被删库跑路了如何正确恢复?( o )… 感觉越来越扯到DBA的活儿上去了。
RedoLog
可以先通过下面demo理解:
饭点记账可以把账单写在账本上也可以写在粉板上。有人赊账或者还账的话,一般有两种做法:
1、直接把账本翻出来,把这次赊的账加上去或者扣除掉。
2、先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。
生意忙时选后者,因为前者太麻烦了。得在密密麻麻的记录中找到这个人的赊账总额信息,找到之后再拿出算盘计算,最后再将结果写回到账本上。
同样在MySQL中如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高。而粉板和账本配合的整个过程就是MySQL用到的是Write-Ahead Logging 技术,它的关键点就是先写日志,再写磁盘。此时账本 = BinLog,粉板 = RedoLog。
1、 记录更新时,InnoDB引擎就会先把记录写到RedoLog(粉板)里面,并更新内存。同时,InnoDB引擎会在空闲时将这个操作记录更新到磁盘里面。
2、 如果更新太多RedoLog处理不了的时候,需先将RedoLog部分数据写到磁盘,然后擦除RedoLog部分数据。RedoLog类似转盘。
RedoLog有write pos 跟checkpoint
write pos :是当前记录的位置,一边写一边后移,写到第3号文件末尾后就回到0号文件开头。
check point:是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
write pos和check point之间的是粉板上还空着的部分,可以用来记录新的操作。如果write pos追上checkpoint,表示粉板满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把checkpoint推进一下。
有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。 redolog两阶段提交:为了让binlog跟redolog两份日志之间的逻辑一致。提交流程大致如下:
1 prepare阶段 --> 2 写binlog --> 3 commit
当在2之前崩溃时,重启恢复后发现没有commit,回滚。备份恢复:没有binlog 。一致
当在3之前崩溃时,重启恢复发现虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog. 一致
binlog跟redolog区别:
redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
redo log是物理日志,记录的是在某个数据页上做了什么修改;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如给ID=2这一行的c字段加1。
redo log是循环写的,空间固定会用完;binlog是可以追加写入的。追加写是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
UndoLog
UndoLog 一般是逻辑日志,主要分为两种:
insert undo log
代表事务在insert新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
update undo log
事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
3、MySQL中的索引
索引的常见模型有哈希表、有序数组和搜索树。
哈希表:一种以KV存储数据的结构,只适合等值查询,不适合范围查询。
有序数组:只适用于静态存储引擎,涉及到插入的时候比较麻烦。可以参考Java中的ArrayList。
搜索树:按照数据结构中的二叉树来存储数据,不过此时是N叉树(B+树)。广泛应用在存储引擎层中。
B+树比B树优势在于:
B+ 树非叶子节点存储的只是索引,可以存储的更多。B+树比B树更加矮胖,IO次数更少。
B+ 树叶子节点前后管理,更加方便范围查询。同时结果都在叶子节点,查询效率稳定。
B+树中更有利于对数据扫描,可以避免B树的回溯扫描。
索引的优点:
1、唯一索引可以保证每一行数据的唯一性
2、提高查询速度
3、加速表与表的连接
4、显着的减少查询中分组和排序的时间
5、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点:
1、创建跟维护都需要耗时
2、创建索引时,需要对表加锁,在锁表的同时,可能会影响到其他的数据操作
3、 索引需要磁盘的空间进行存储,磁盘占用也很快。
4、当对表中的数据进行CRUD的时,也会触发索引的维护,而维护索引需要时间,可能会降低数据操作性能
索引设计的原则不应该:
1、索引不是越多越好。索引太多,维护索引需要时间跟空间。
2、 频繁更新的数据,不宜建索引。
3、数据量小的表没必要建立索引。
应该:
1、重复率小的列建议生成索引。因为重复数据少,索引树查询更有效率,等价基数越大越好。
2、数据具有唯一性,建议生成唯一性索引。在数据库的层面,保证数据正确性
3、频繁group by、order by的列建议生成索引。可以大幅提高分组和排序效率
4、经常用于查询条件的字段建议生成索引。通过索引查询,速度更快
索引失效的场景
1、模糊搜索:左模糊或全模糊都会导致索引失效,比如'%a'和'%a%'。但是右模糊是可以利用索引的,比如'a%' 。
2、隐式类型转换:比如select * from t where name = xxx , name是字符串类型,但是没有加引号,所以是由MySQL隐式转换的,所以会让索引失效 3、当语句中带有or的时候:比如select * from t where name=‘sw’ or age=14
4、不符合联合索引的最左前缀匹配:(A,B,C)的联合索引,你只where了C或B或只有B,C
关于索引的知识点:
主键索引:主键索引的叶子节点存的是整行数据信息。在InnoDB里,主键索引也被称为聚簇索引(clustered index)。主键自增是无法保证完全自增的哦,遇到唯一键冲突、事务回滚等都可能导致不连续。
唯一索引:以唯一列生成的索引,该列不允许有重复值,但允许有空值(NULL)
普通索引跟唯一索引查询性能:InnoDB的数据是按数据页为单位来读写的,默认每页16KB,因此这两种索引查询数据性能差别微乎其微。
change buffer:普通索引用在更新过程的加速,更新的字段如果在缓存中,如果是普通索引则直接更新即可。如果是唯一索引需要将所有数据读入内存来确保不违背唯一性,所以尽量用普通索引。
非主键索引:非主键索引的叶子节点内容是主键的值。在InnoDB里,非主键索引也被称为二级索引(secondary index)
回表:先通过数据库索引扫描出数据所在的行,再通过行主键id取出索引中未提供的数据,即基于非主键索引的查询需要多扫描一棵索引树。
覆盖索引:如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为覆盖索引。
联合索引:相对单列索引,组合索引是用多个列组合构建的索引,一次性最多联合16个。
最左前缀原则:对多个字段同时建立的组合索引(有顺序,ABC,ACB是完全不同的两种联合索引) 以联合索引(a,b,c)为例,建立这样的索引相当于建立了索引a、ab、abc三个索引。另外组合索引实际还是一个索引,并非真的创建了多个索引,只是产生的效果等价于产生多个索引。
索引下推:MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数。
索引维护:B+树为了维护索引有序性涉及到页分裂跟页合并。增删数据时需考虑页空间利用率。
自增主键:一般会建立与业务无关的自增主键,不会触发叶子节点分裂。
延迟关联:通过使用覆盖索引查询返回需要的主键,再根据主键关联原表获得需要的数据。
InnoDB存储: * .frm文件是一份定义文件,也就是定义数据库表是一张怎么样的表。*.ibd文件则是该表的索引,数据存储文件,既该表的所有索引树,所有行记录数据都存储在该文件中。
MyISAM存储:* .frm文件是一份定义文件,也就是定义数据库表是一张怎么样的表。* .MYD文件是MyISAM存储引擎表的所有行数据的文件。* .MYI文件存放的是MyISAM存储引擎表的索引相关数据的文件。MyISAM引擎下,表数据和表索引数据是分开存储的。
MyISAM查询:在MyISAM下,主键索引和辅助键索引都属于非聚簇索引。查询不管是走主键索引,还是非主键索引,在叶子结点得到的都是目的数据的地址,还需要通过该地址,才能在数据文件中找到目的数据。
PS:InnoDB支持聚簇索引,MyISAM不支持聚簇索引
4、SQL事务隔离级别
ACID的四个特性
原子性(Atomicity):把多个操作放到一个事务中,保证这些操作要么都成功,要么都不成功
一致性(Consistency):理解成一串对数据进行操作的程序执行下来,不会对数据产生不好的影响,比如凭空产生,或消失
隔离性(Isolation,又称独立性):隔离性的意思就是多个事务之间互相不干扰,即使是并发事务的情况下,他们只是两个并发执行没有交集,互不影响的东西;当然实现中,也不一定需要这么完整隔离性,即不一定需要这么的互不干扰,有时候还是允许有部分干扰的。所以MySQL可以支持4种事务隔离性
持久性(Durability):当某个操作操作完毕了,那么结果就是这样了,并且这个操作会持久化到日志记录中
PS:ACID中C与CAP定理中C的区别
ACID的C着重强调单数据库事务操作时,要保证数据的完整和正确性,数据不会凭空消失跟增加。CAP 理论中的C指的是对一个数据多个备份的读写一致性
事务操作可能会出现的数据问题
1、脏读(dirty read):B事务更改数据还未提交,A事务已经看到并且用了。B事务如果回滚,则A事务做错了
2、 不可重复读(non-repeatable read):不可重复读的重点是修改: 同样的条件, 你读取过的数据, 再次读取出来发现值不一样了,只需要锁住满足条件的记录
3、 幻读(phantom read):事务A先修改了某个表的所有纪录的状态字段为已处理,未提交;事务B也在此时新增了一条未处理的记录,并提交了;事务A随后查询记录,却发现有一条记录是未处理的造成幻读现象,幻读仅专指新插入的行。幻读会造成语义上的问题跟数据一致性问题。
4、 在可重复读RR隔离级别下,普通查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在当前读下才会出现。要用间隙锁解决此问题。
在说隔离级别之前,你首先要知道,你隔离得越严实,效率就会越低。因此很多时候,我们都要在二者之间寻找一个平衡点。SQL标准的事务隔离级别由低到高如下: 上图从上到下的模式会导致系统的并行性能依次降低,安全性依次提高。
读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。
读已提交(Oracle默认):别人改数据的事务已经提交,我在我的事务中才能读到。
可重复读(MySQL默认):别人改数据的事务已经提交,我在我的事务中也不去读,以此保证重复读一致性。
串行:我的事务尚未提交,别人就别想改数据。
标准跟实现:上面都是关于事务的标准,但是每一种数据库都有不同的实现,比如MySQL InnDB 默认为RR级别,但是不会出现幻读。因为当事务A更新了所有记录的某个字段,此时事务A会获得对这个表的表锁,因为事务A还没有提交,所以事务A获得的锁没有释放,此时事务B在该表插入新记录,会因为无法获得该表的锁,则导致插入操作被阻塞。只有事务A提交了事务后,释放了锁,事务B才能进行接下去的操作。所以可以说 MySQL的RR级别的隔离是已经实现解决了脏读,不可重复读和幻读的。
5、MySQL中的锁
无论是Java的并发编程还是数据库的并发操作都会涉及到锁,研发人员引入了悲观锁跟乐观锁这样一种锁的设计思想。
悲观锁:
优点:适合在写多读少的并发环境中使用,虽然无法维持非常高的性能,但是在乐观锁无法提更好的性能前提下,可以做到数据的安全性
缺点:加锁会增加系统开销,虽然能保证数据的安全,但数据处理吞吐量低,不适合在读书写少的场合下使用
乐观锁:
优点:在读多写少的并发场景下,可以避免数据库加锁的开销,提高DAO层的响应性能,很多情况下ORM工具都有带有乐观锁的实现,所以这些方法不一定需要我们人为的去实现。
缺点:在写多读少的并发场景下,即在写操作竞争激烈的情况下,会导致CAS多次重试,冲突频率过高,导致开销比悲观锁更高。
实现:数据库层面的乐观锁其实跟CAS思想类似, 通数据版本号或者时间戳也可以实现。
数据库并发场景主要有三种:
读-读:不存在任何问题,也不需要并发控制
读-写:有隔离性问题,可能遇到脏读,幻读,不可重复读
写-写:可能存更新丢失问题,比如第一类更新丢失,第二类更新丢失
两类更新丢失问题:
第一类更新丢失:事务A的事务回滚覆盖了事务B已提交的结果 第二类更新丢失:事务A的提交覆盖了事务B已提交的结果
为了合理贯彻落实锁的思想,MySQL中引入了杂七杂八的各种锁:
锁分类
MySQL支持三种层级的锁定,分别为
表级锁定
MySQL中锁定粒度最大的一种锁,最常使用的MYISAM与INNODB都支持表级锁定。
页级锁定
是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁,表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。
行级锁定
Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大行级锁不一定比表级锁要好:锁的粒度越细,代价越高,相比表级锁在表的头部直接加锁,行级锁还要扫描找到对应的行对其上锁,这样的代价其实是比较高的,所以表锁和行锁各有所长。
MyISAM中的锁
虽然MySQL支持表,页,行三级锁定,但MyISAM存储引擎只支持表锁。所以MyISAM的加锁相对比较开销低,但数据操作的并发性能相对就不高。但如果写操作都是尾插入,那还是可以支持一定程度的读写并发
从MyISAM所支持的锁中也可以看出,MyISAM是一个支持读读并发,但不支持通用读写并发,写写并发的数据库引擎,所以它更适合用于读多写少的应用场合,一般工程中也用的较少。
InnoDB中的锁
该模式下支持的锁实在是太多了,具体如下:
共享锁和排他锁 (Shared and Exclusive Locks)
意向锁(Intention Locks)
记录锁(Record Locks)
间隙锁(Gap Locks)
临键锁 (Next-Key Locks)
插入意向锁(Insert Intention Locks)
主键自增锁 (AUTO-INC Locks)
空间索引断言锁(Predicate Locks for Spatial Indexes)
举个栗子,比如行锁里的共享锁跟排它锁:lock in share modle 共享读锁:
为了确保自己查到的数据没有被其他的事务正在修改,也就是说确保查到的数据是最新的数据,并且不允许其他人来修改数据。但是自己不一定能够修改数据,因为有可能其他的事务也对这些数据使用了 in share mode 的方式上了S 锁。如果不及时的commit 或者rollback 也可能会造成大量的事务等待。
for update排它写锁:
为了让自己查到的数据确保是最新数据,并且查到后的数据只允许自己来修改的时候,需要用到for update。相当于一个 update 语句。在业务繁忙的情况下,如果事务没有及时的commit或者rollback 可能会造成其他事务长时间的等待,从而影响数据库的并发使用效率。
Gap Lock间隙锁:
1、行锁只能锁住行,如果在记录之间的间隙插入数据就无法解决了,因此MySQL引入了间隙锁(Gap Lock)。间隙锁是左右开区间。间隙锁之间不会冲突。
2、间隙锁和行锁合称NextKeyLock,每个NextKeyLock是前开后闭区间。
间隙锁加锁原则(学完忘那种):
1、加锁的基本单位是 NextKeyLock,是前开后闭区间。
2、查找过程中访问到的对象才会加锁。
3、索引上的等值查询,给唯一索引加锁的时候,NextKeyLock退化为行锁。
4、索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,NextKeyLock退化为间隙锁。
5、唯一索引上的范围查询会访问到不满足条件的第一个值为止。
⑶ sql server有联合主键是否也有联合索引,怎样创建联合索引
create index 索引名 on 表名(字段名1,字段名2,...字段名n)
⑷ 联合索引
本文预计分为两个部分:
(1)联合索引部分的基础知识
在这个部分,我们温习一下联合索引的基础
(2)联合索引部分的实战题
在这个部分,列举几个我认为算是实战中的代表题,挑出来带冲说说。
正文
基础
讲联合索引,一定要扯最左匹配!放心,我不扯有的没的,几句话懂个大概就行!
最左匹配
所谓最左原则指的就是如果你的 SQL 语句中用到了联合索引中的最左边的索引,掘行晌那么这条 SQL 语句就可以利用这个联合索引去进行匹配,值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。
假设,我们对(a,b)字段建立一个索引,也就是说,你where后条件为
a=1a=1and b =2
是可以匹配索引的。但是要注意的是~你执行
b=2and a =1
也是能匹配到索引的,因为Mysql有优化器会自动调整a,b的顺序与索引顺序一致。
相反的,你执行
b=2
就匹配不到索引了。
而你对(a,b,c,d)建立索引,where后条件为
a =1andb =2andc >3andd =4
那么,a,b,c三个字段能用到索引,而d就匹配不到。因为遇到了范围查询!
最左匹配的原理?
假设,我们对判锋(a,b)字段建立索引,那么入下图所示
如图所示他们是按照a来进行排序,在a相等的情况下,才按b来排序。
因此,我们可以看到a是有序的1,1,2,2,3,3。而b是一种全局无序,局部相对有序状态!
什么意思呢?
从全局来看,b的值为1,2,1,4,1,2,是无序的,因此直接执行b = 2这种查询条件没有办法利用索引。
从局部来看,当a的值确定的时候,b是有序的。例如a = 1时,b值为1,2是有序的状态。当a=2时候,b的值为1,4也是有序状态。
因此,你执行a = 1 and b = 2是a,b字段能用到索引的。而你执行a > 1 and b = 2时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这个范围内b值不是有序的,因此b字段用不上索引。
综上所示,最左匹配原则,在遇到范围查询的时候,就会停止匹配。
实战
OK,懂上面的基础,我们就可以开始扯了~我举了经典的五大题型,看完基本就懂!
题型一
如果sql为
SELECT*FROMtableWHEREa =1andb =2andc =3;
如何建立索引?
如果此题回答为对(a,b,c)建立索引,那都可以回去等通知了。
此题正确答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以,重点要的是将区分度高的字段放在前面,区分度低的字段放后面。像性别、状态这种字段区分度就很低,我们一般放后面。
例如假设区分度由大到小为b,a,c。那么我们就对(b,a,c)建立索引。在执行sql的时候,优化器会 帮我们调整where后a,b,c的顺序,让我们用上索引。
题型二
如果sql为
SELECT*FROMtableWHEREa >1andb =2;
如何建立索引?
如果此题回答为对(a,b)建立索引,那都可以回去等通知了。
此题正确答法是,对(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,毕竟最左匹配原则遇到范围查询就停止匹配。
如果对(b,a)建立索引那么两个字段都能用上,优化器会帮我们调整where后a,b的顺序,让我们用上索引。
题型三
如果sql为
SELECT*FROM`table`WHEREa >1andb =2andc >3;
如何建立索引?
此题回答也是不一定,(b,a)或者(b,c)都可以,要结合具体情况具体分析。
拓展一下
SELECT*FROM`table`WHEREa =1andb =2andc >3;
怎么建索引?嗯,大家一定都懂了!
题型四
SELECT*FROM`table`WHEREa =1ORDERBYb;
如何建立索引?
这还需要想?一看就是对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序!
那么
SELECT*FROM`table`WHEREa >1ORDERBYb;
如何建立索引?
对(a)建立索引,因为a的值是一个范围,这个范围内b值是无序的,没有必要对(a,b)建立索引。
拓展一下
SELECT*FROM`table`WHEREa =1ANDb =2ANDc >3ORDERBYc;
怎么建索引?
题型五
SELECT*FROM`table`WHEREaIN(1,2,3)andb >1;
如何建立索引?
还是对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配,所以还是(a,b)!
拓展一下
SELECT*FROM`table`WHEREa =1ANDbIN(1,2,3)ANDc >3ORDERBYc;
如何建立索引?此时c排序是用不到索引的。
⑸ SQL不走索引的可能原因
1、联合索引,查询条件没有联合樱正索引的第一列。
2、在包含有null值的table列上建立索引,当时使用select count(*) from table时不会使用索引。
3、在索引列上使用函数时不会使用索引,如果一定要使用索引只能建立函数索引。
4、当被索引的列进行隐式码大的类型转换时不会使用索引。
5、使用 IS NULL 和 IS NOT NULL
6、使用 LIKE ‘%T’ 进行模糊查询,要脊模悔走索引,like的后面不能以%开头
7、WHERE 子句中使用不等于操作
8、等于和范围索引不会被合并使用
⑹ mysql数据库创建两张表之间的联合索引的sql语句,示例就可以!多谢
ALTERTABLEOrdersADDFOREIGNKEY(Id_P)
REFERENCESPersons(Id_P)
⑺ mysql建表时如何把两个字段加一起指定为唯一索引
mysql无法在建表时把两个字段加一起指定岁埋做为唯一索引。mysql设置联合唯一索引方法如下:使用Altertable表名addUNIQUEindex索引名(字段1,字段2)语液巧句来设置,它会删除重复的乎衡记录,保留一条,然后建立联合唯一索引。
⑻ 联合索引(x+y),那么sql语句的where条件上大于小于范围的哪种写法效率高
1、首先复合索引中列的次序很重要,如果index on (x,y),一般来说x的选择性要比y的选择性高比较好,如果x的选择性足和蠢够高,只对单列x提条件时也可能会用上这个索引
2、你这2个条件对于目前的大型数据库没差别,数据库在做执行亩棚基计划都会进行优化,当然代码还是尽量做到不依赖于数据库的优化
3、如果想优化这个条件,个人觉得应该写成迅谨 x between 11 and 49 and y between 11 and 49,如果复合索引中x在y前
⑼ Mysql建立索引经验
在实际开发中使用数据库时,难免会遇到一些大表数据,对这些数据进行查询时,有时候SQL会查询得特别慢,这时候,有经验的老师傅会告诉你,你看一下哪几个字段查的多,加一个索引就好了。
那么,怎么合理地建立索引呢?这里分享一下我的一些经验,如有不妥之处,欢迎批评指正。
1、不要盲目建立索引 , 先分析再创建
索引虽然能大幅度提升我们的查询性能,但也要知道,在你进行增删改时,索引树也要同样地进行维护。所以,索引不是越多越好,而是按需建立。最好是在一整块模块开发完成后,分析一下,去针对大多数的查询,建立联合索引。
2、使用联合索引尽量覆盖多的条件
这是说在一个慢sql里假如有五个where ,一个 order by ,那么我们的联合索引尽量覆盖到这五个查询条件,如果有必要,order by 也覆盖上 。
3、小基数字段不需要索引
这个意思是,如果一张表里某个字段的值只有那么几个,那么你针对这个字段建立的索引其实没什么意义,比如说,一个性别字段就两种结果,你建了索引,排序也没什么意思(也就是索引里把男女给分开了)
所以说,索引尽量选择基数大的数据去建立宴肆,能最大化地利用索引
4、长字符串可以使用前缀索引
我们建立索引的字段尽量选择字段类型知唤较小的,比如一个varchar(20)和varchar(256)的,我们在20的上晌猛轿面建立的索引和在256上就有明显的差距(字符串那么长排序也不好排呀,唉)。
当然,如果一定是要对varchar(256)建立索引,我们可以选择里面的前20个字符放在索引树里(这里的20不绝对,选择能尽量分辨数据的最小字符字段设计),类似这样KEY index(name(20),age,job) ,索引只会对name的前20个字符进行搜索,但前缀索引无法适用于order by 和 group by。
5、对排序字段设计索引的优先级低
如果一个SQL里我们出现了范围查找,后边又跟着一个排序字段,那么我们优先给范围查找的字段设置索引,而不是优先排序。
6、如果出现慢SQL,可以设计一个只针对该条SQL的联合索引。
不过慢SQL的优化,需要一步步去进行分析,可以先用explain查看SQL语句的分析结果,再针对结果去做相应的改进。explain的东西我们下次再讲。
PS:在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是 执行这条SQL。
⑽ SQL Server 怎么建立联合主键
建立联合主键有两种方式:
一种是在建表时就写出,语句如下:
Create Table 表名 (字段名1 Int Not Null,
字段名2 nvarchar(13) Not Null Primary Key (字段名1, 字段名2),
字段名3…………
字段名N………… )
另一种是在建表后更改,语句如下:
alter table 你的表名 add constraint pk_你的表名 primary key (字段1,字段2)
ALTER TABLE 表名 WITH NOCHECK ADD
CONSTRAINT [PK_表名] PRIMARY KEY NONCLUSTERED
(
[字段名1],
[字段名2]
)
创建联合主键还可以这样写:
create table huayunkeji_today(device_id int , year int, month int, day int, hour int, temperature float, humidity float,
primary key(device_id,year,month,day,hour));
(10)建立联合索引的sql扩展阅读:
联合主键的使用情况及优点:
联合主键就是用2个或2个以上的字段组成主键。用这个主键包含的字段作为主键,这个组合在数据表中是唯一,且加了主键索引。
可以这么理解,比如,你的订单表里有很多字段,一般情况只要有个订单号bill_no做主键就可以了,但是,现在要求可能会有补充订单,使用相同的订单号,那么这时单独使用订单号就不可以了。
再使用个订单序列号bill_seq来作为区别。把bill_no和bill_seq设成联合主键。即使bill_no相同,bill_seq不同也是可以的。