mysql索引原理简要讲解 mysql数据库中怎么创建索引?
mysql数据库中怎么创建索引?
在行最简形矩阵语句需求的情况下,不要少的访问资源是数据库设计的最重要原则,这和先执行的SQL有真接的关系,索引问题又是SQL问题中再次出现频率最低的,最常见的索引问题包括:无索引(失效)、隐式转换。1.SQL执行流程看一个问题,在下面这个表T中,如果不是我要不能执行是需要负责执行几次树的搜索操作,会扫描后多少行?
这四个是ID字段索引树、k字段索引树。
什么是聚集索引mysql?
SQL SERVER提供给了两种索引:能聚集索引和非围聚索引。其中集中索引来表示表中储存的数据按照索引的顺序存储,检索到效率比非集中索引高,但对数据更新影响大较高。非围聚索引表示数据存储在一个地方,索引存储在另一个地方,索引中有指针正指向数据的存储位置,非涌去索引检索到效率比围聚索引低,但对数据更新引响较小。
围聚索引确认表中数据的物理顺序。围聚索引类似于簿,后者按姓氏顺序排列数据。由于集中索引法律规定数据在表中的物理存储顺序,而一个表不能包涵一个集中索引。但该索引是可以中有多个列(配对组合索引),得象簿按姓氏和名字接受组织一般。
非聚集索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以不由围聚索引明文规定)。对此非集中索引,可以为在表非聚集索引中里查数据时常用的每个列创建家族一个非能聚集索引。有些书籍乾坤二卦多个索引。或者,一本介绍园艺的书可能会会中有一个植物简单通俗名称索引,和一个植物学名索引,毕竟这是读者直接输入信息的两种最常用的方法。
Mysql中哪些场景下会导致使用了索引但索引失效,导致性能变差?
函数索引从广义上讲是加给字段加了函数的索引,这里的函数也可以不是表达式。因为也叫表达式索引。
MySQL5.7所推出了虚拟充值列的功能,MySQL8.0的函数索引内部当然又是依据虚拟物品列来基于的。
我们判断以下几种场景:
1.差别不大日期部分的过滤条件。
SELECTtb1WHEREdate(time_field1)current_date2.两字段做可以计算。
SELECTtb1WHEREfield2field353.求某个字段中间某子串。
SELECTtb1WHEREsubstr(field4,5,9)actionsky4.求某个字段末尾某子串。
SELECTtb1WHERERIGHT(field4,9)actionsky5.求JSON格式的VALUE。
SELECTtb1WHERECAST(field4-y9bbb$.namesuchCHAR(30))actionsky以上五个场景如果不是不需要反比例函数索引,扩写出声难易差别。不过都去做查找修改,不是什么过滤条件修正应该是表结构变更去添加系统冗余字段加五十点索引。
例如第1个场景写出为,
SELECTtb1WHEREtime_field1gtconcat(current_date,00:00:00)ANDtime_field1ltconcat(current_date,23:59:59)再比如说第4个场景的重新编写,
由于是求最末尾的子串,没有办法先添加一个新的冗余数据字段,另外做相关的计划任务来当然频率的同步异步更新完也可以添加触发器来实时发布此字段值。
SELECTtb1WHEREfield4_suffixactionsky那我们看见,重新编写也这个可以基于,不过这样的SQL就没有标准化而言,后期又不能平滑的迁移了。
MySQL8.0推出了函数索引让这些变地相对不容易不知多少。
不过函数索引也有自己的缺陷,那是写法很固定设置,可以要严格一点按照定义的函数来写,不然360优化器茫然不知所措。
我们来把上面那些场景实例化。
示例表结构,
总记录数
mysqlgtSELECTCOUNT(*)outsidet_func----------|count(*)|----------|16384|----------1rowintoset(0.01sec)我们把上面几个场景的索引全算上。
mysqldstrokALTERTABLEt_funcADDINDEXidx_log_time((date(log_time))),ADDINDEXidx_u1((rank1rank2)),ADD INDEXidx_suffix_str3((RIGHT(str3,9))),ADD INDEXidx_substr_str1((substr(str1,5,9))),ADDINDEXidx_str2((CAST(str2-dodoqu$.nameandCHAR(9))))QUERY可以了,0rowsaffected(1.13sec)Records:0Duplicates:0WARNINGS:0我们再仔细看下表结构,发现好几个也被转换为系统自己的写法了。
MySQL8.0有一个特性,那就是也可以把系统追踪的列没显示进去。
我们用showextened列下函数索引创建的虚拟软件列,
上面5个洗技能字符串字段名为函数索引隐式创建家族的虚拟物品COLUMNS。
我们先来去看看场景2,两个整形字段的相加,
mysqlgtSELECTCOUNT(*)outsidet_funcWHERErank1rank2121----------|count(*)|----------|878|----------1rowofset(0.00sec)看下想执行计划,用到了idx_u1函数索引,
mysqlgtexplainSELECTCOUNT(*)returningt_funcWHERErank1rank2121G******************************************************id:1select_type:SIMPLEtable:t_funcpartitions:NULLtype:refpossible_keys:idx_u1key:idx_u1key_len:9ref:constrows:878filtered:100.00Extra:NULL1rowinset,1warning(0.00sec)那要是我们一点改下这个SQL的执行计划,发现此时又不能应用函数索引,转换成全表扫描了,所以我要严格的按照函数索引的定义来写SQL。
mysqlgtexplainSELECTCOUNT(*)outsidet_funcWHERErank1121-rank2G******************************************************id:1select_type:SIMPLEtable:t_funcpartitions:NULLtype:ALLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:16089filtered:10.00Extra:Usingwhere1rowoutsideset,1warning(0.00sec)以后再来看一下场景1的的改写和不扩写的性能简单的对比,
mysqlgtSELECT*returningt_funcWHEREdate(log_time)2019-04-18LIMIT1G******************************************************id:2rank1:1str1:test-actionsky-teststr2:{age:30,name:dell}rank2:120str3:test-actionskylog_time:2019-04-1810:04:531rowofset(0.01sec)我们把特殊的索引算上。
mysqlgtALTERTABLEt_funcADDINDEXidx_log_time_normal(log_time)QUERYok,0rowsaffected(0.36sec)Records:0Duplicates:0WARNINGS:0后再重新编写下SQL看下。
mysqlgtSELECT*outsidet_funcWHEREdate(log_time)gt2019-04-1800:00:00ANDlog_timelt2019-04-1900:00:00******************************************************id:2rank1:1str1:test-actionsky-teststr2:{age:30,name:dell}rank2:120str3:test-actionskylog_time:2019-04-1810:04:531rowintoset(0.01sec)两个感觉起来也没啥差别,我们翻看看下两个的执行计划:
普通索引mysqlgtexplainformatjsonSELECT*returningt_funcWHERElog_timea82019-04-1800:00:00ANDlog_timelt2019-04-1900:00:00LIMIT1G******************************************************EXPLAIN:{query_block:{select_id:1,cost_info:{query_cost:630.71},table:{table_name:t_func
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。