数据库相关(1)-- Mysql索引

M ysql索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不是越多越好,假如这本书1000页,有500也是目录,它当然效率低,目录是要占纸张的,而索引是要占磁盘空间的。

Mysql常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引

PRIMARY KEY(主键索引) 

    CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) )

    ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )

UNIQUE(唯一索引)    

    CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表)

    ALTER TABLE `table_name` ADD UNIQUE (`column`)

INDEX(普通索引)    

    创建索引,CREATE INDEX <索引的名字> ON tablename (列的列表);

    修改索引,ALTER TABLE `table_name` ADD INDEX index_name ( `column` )

    创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) )

FULLTEXT(全文索引)     

    ALTER TABLE `table_name` ADD FULLTEXT ( `column` )

组合索引

    ALTER TABLE `table_name` ADD INDEX index_name ( `column1`,`column2`, `column3` )


Mysql各种索引区别:

普通索引:最基本的索引,没有任何限制。

唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。

主键索引:它是一种特殊的唯一索引,不允许有空值。

全文索引:仅可用于MyISAM表,针对较大的数据,生成全文索引很耗时好空间。

组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。


讲下你项目里做的数据库索引优化,如何去分析一条语句的执行性能,explain语句你会关注哪些字段

索引优化策略:

 *最左前缀匹配原则,上面讲到了

 *主键外检一定要建索引

 *对 where,on,group by,order by 中出现的列使用索引

 *尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0。对较小的数据列使用索引,这样会使索引文件更小,同时内存中也可以装载更多的索引键

 *索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);

 *为较长的字符串使用前缀索引

 *尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可,不要过多创建索引, 权衡索引个数与DML之间关系,DML也就是插入、删除数据操作。这里需要权衡一个问题,建立索引的目的是为了提高查询效率的,但建立的索引过多,会影响插入、删除数据的速度,因为我们修改的表数据,索引也需要进行调整重建

 *对于like查询,”%”不要放在前面。

   SELECT * FROM houdunwang WHERE uname LIKE '后盾%' -- 走索引

   SELECT *FROM houdunwang WHERE uname LIKE  '%后盾%' -- 不走索引

 *查询where条件数据类型不匹配也无法使用索引

 *字符串与数字比较不使用索引;

CREATE TABLE a(a char(10));

EXPLAIN SELECT * FROM a WHERE a="1" – 走索引

EXPLAIN SELECT * FROM a WHERE a=1 – 不走索引

正则表达式不使用索引,这应该很好理解,所以为什么在SQL中很难看到regexp关键字的原因


Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效果,可以帮助选择更好的索引和优化查询语句,写出更好的优化语句。

Explain语法:

EXPLAIN

tbl_name或:EXPLAIN[EXTENDED] SELECT select_options

前者可以得出一个表的字段结构等等,后者主要是给出相关的一些索引信息,而今天要讲述的重点是后者。

例如:

EXPLAIN

  SELECT sum(amount)

FROM customer a, payment b

  WHERE1 = 1

AND a.customer_id = b.customer_id

AND a.email = 'JANE.BENNETT@sakilacustomer.org';

执行结果:

下面对各个属性进行了解:

1、id:这是SELECT的查询序列号。每个 SELECT 都会自动分配一个唯一的标识符。

2、select_type:select_type就是select的类型,可以有以下几种:

    SIMPLE:简单SELECT(不使用UNION或子查询等)

    PRIMARY:最外面的SELECT

    UNION:UNION中的第二个或后面的SELECT语句

    DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询

    UNION RESULT:UNION的结果。

    SUBQUERY:子查询中的第一个SELECT

    DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

    DERIVED:导出表的SELECT(FROM子句的子查询)

3、table:显示这一行的数据是关于哪张表的实际的表名(如select * from customer;) 或表的别名 (如 select * from customer a);

4、type:这列最重要,显示了连接使用了哪种类别,有无使用索引,是使用Explain命令分析性能瓶颈的关键项之一。通过 type 字段, 我们判断此次查询是 全表扫描 还是 索引扫描等。

system > const > eq_ref > ref > fulltext >ref_or_null > index_merge > unique_subquery > index_subquery >range > index > ALL

一般来说,得保证查询至少达到range级别,最好能达到ref,否则就可能会出现性能问题。

    ● all: 意味着从表的第1行,往后逐行做全表扫描,运气不好扫描到最后一行。

    ● index:表示全索引扫描(full index scan),和 ALL 类型类似,只不过 ALL 类型是全表扫描, 而 index 类型则仅仅扫描所有的索引, 而不扫描数据。比all性能稍好一点,通俗的说: all 扫描所有的数据行,相当于data_all index 扫描所有的索引节点,相当于index_all。注:all是沿着磁盘扫描,index是沿着索引扫描。例如:EXPLAIN SELECT name FROM user_info。上面的例子中, 我们查询的 name 字段恰好是一个索引, 因此我们直接从索引中获取数据就可以满足查询的需求了, 而不需要查询表中的数据. 因此这样的情况下, type 的值是 index, 并且 Extra 的值是Using Index。

    ● range: 意思是查询时,能根据索引做范围的扫描。表示使用索引范围查询,通过索引字段范围获取表中部分数据记录。这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中。当 type 是 range 时, 那么 EXPLAIN 输出的 ref 字段为 NULL, 并且 key_len 字段是此次查询中使用到的索引的最长的那个。例如,EXPLAIN SELECT * FROM user_info WHERE id BETWEEN 2 AND 8。

    ● index_subquery 在子查询中,基于除唯一索引之外的索引进行扫描;

    ● unique_subquery在子查询中,基于唯一索引进行扫描,类似于EQ_REF;

    ● index_merge 多重范围扫描。两表连接的每个表的连接字段上均有索引存在且索引有序,结果合并在一起。适用于作集合的并、交操作。

    ● ref_or_null 类似REF,只是搜索条件包括:连接字段的值可以为NULL的情况,比如where col = 2 or col is null

    ● fulltext 全文索引

    ● ref 此类型通常出现在多表的 join 查询。针对于非唯一或非主键索引,或者是使用了最左前缀 规则索引的查询(也是范围区间,不过比range更加精确)。例如,EXPLAIN SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id AND order_info.user_id = 5。

    ● eq_ref是指通过索引列,直接引用某1行数据(精确到一行数据中)常见于连接查询中,表示对于前表的每一个结果,都只能匹配到后表的一行结果。并且查询的比较操作通常是 =,查询效率较高。例如,EXPLAIN SELECT * FROM user_info,order_info WHERE user_info.id = order_info.user_id。

    ● const, system, null 当mysql能对查询的部分就行优化,并且转换成一个常量的时候,它就会使用这种访问类型了。比如你把一行的主键当做where条件放进去,那mysql就可以把它转换成一个常量,然后查询。例如,explain select * from user_info where id = 2。

5、possible_keys:列指出MySQL能使用哪个索引在该表中找到行

6、key:此字段是 MySQL 在当前查询时所真正使用到的索引。如果没有选择索引,键是NULL。

7、key_len:显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好

8、ref:显示使用哪个列或常数与key一起从表中选择行。

9、rows:显示MySQL认为它执行查询时必须检查的行数。rows 也是一个重要的字段。

      MySQL查询优化器根据统计信息, 估算 SQL 要查找到结果集需要扫描读取的数据行数。这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好。

10、Extra:包含MySQL解决查询的详细信息,也是关键参考项之一。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容

  • 一、MySQL优化 MySQL优化从哪些方面入手: (1)存储层(数据) 构建良好的数据结构。可以大大的提升我们S...
    宠辱不惊丶岁月静好阅读 2,425评论 1 8
  • 转载:http://blog.codinglabs.org/articles/theory-of-mysql-in...
    qf1007阅读 1,289评论 0 0
  • MySql数据库索引原理 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点。考虑...
    琴匣自鸣阅读 1,683评论 0 2
  • 本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有MyS...
    Chting阅读 598评论 0 1
  • “10年之后,你若未嫁,我若未娶,我们便在一起”,在很多人看来,这是句温暖的告白,在那么一刹那也让我深信不疑。然而...
    Sunnylemonnnn阅读 200评论 0 0