什么是索引?

1、索引

索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。

2、索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。

索引由数据库中一列或多列组合而成,其作用是提高对表中数据的查询速度
索引的优点是可以提高检索数据的速度
索引的缺点是创建和维护索引需要耗费时间
索引可以提高查询速度,会减慢写入速度

索引分类

1.普通索引
2.唯一索引
3.全文索引
4.单列索引
5.多列索引
6.空间索引
7.主键索引
8.组合索引

  • 普通索引:仅加速查询
  • 唯一索引:加速查询 + 列值唯一(可以有null)
  • 主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
  • 组合索引:多列值组成一个索引,
    专门用于组合搜索,其效率大于索引合并
  • 全文索引:对文本的内容进行分词,进行搜索

索引合并,使用多个单列索引组合搜索
覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

如何创建索引?记住一个单词—explain

创建表的时候创建索引

  1. CREATE TABLE tbl_name(
  2. 字段名称 字段类型 [完整性约束条件],
  3. ,,,,
  4. [UNIQUE|FULLTEXT|SPATIAL] INDEX|KEY[索引名称](字段名称[(长度)])
  5. [ASC|DESC]
  6. );

在已经存在的表上创建索引:

  1. .CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名称 ON 表名{字段名称[(长度)] [ASC|DESC]}
  2. .ALTER TABLE tbl_name ADD [UNIQUE|FULLTEXT|SPATIAL] INDEX索引名称(字段名称[(长度)][ASC|DESC]);

如何删除索引?

  1. DROP INDEX 索引名称 ON tbl_name

1.普通索引

普通索引仅有一个功能:加速查询

创建表+索引

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name ) not null,
  4. email ) not null,
  5. extra text,
  6. index ix_name (name)
  7. )

创建索引

  1. create index index_name on table_name(column_name)

删除索引

  1. drop index_name on table_name;

查看索引

  1. show index from table_name;

注意:对于创建索引时如果是BLOB 和 TEXT 类型,必须指定length。

  1. ));

2、唯一索引

唯一索引有两个功能:加速查询 和 唯一约束(可含null)

创建表+唯一索引

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name ) not null,
  4. email ) not null,
  5. extra text,
  6. unique ix_name (name)
  7. )

创建唯一索引

  1. create unique index 索引名 on 表名(列名)

删除唯一索引

  1. drop unique index 索引名 on 表名

3、主键索引

主键有两个功能:加速查询 和 唯一约束(不可含null)

创建表+创建主键

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name ) not null,
  4. email ) not null,
  5. extra text,
  6. index ix_name (name)
  7. )
  8. OR
  9. create table in1(
  10. nid int not null auto_increment,
  11. name ) not null,
  12. email ) not null,
  13. extra text,
  14. primary key(ni1),
  15. index ix_name (name)
  16. )

创建主键

  1. alter table 表名 add primary key(列名);

删除主键

  1. alter table 表名 drop primary key;
  2. alter table 表名 modify 列名 int, drop primary key;

4、组合索引

组合索引是将n个列组合成一个索引

其应用场景为:频繁的同时使用n列来进行查询,如:where n1 = ‘alex’ and n2 = 666。

创建表

  1. create table in3(
  2. nid int not null auto_increment primary key,
  3. name ) not null,
  4. email ) not null,
  5. extra text
  6. )

创建组合索引

  1. create index ix_name_email on in3(name,email);

如上创建组合索引之后,查询:

    1. name and email 使用索引
    2. name 使用索引
    3. email 不使用索引

注意:对于同时搜索n个条件时,组合索引的性能好于多个单一索引合并。

相关命令

  1. - 查看表结构
  2. desc 表名
  3.  
  4. - 查看生成表的SQL
  5. show create table 表名
  6.  
  7. - 查看索引
  8. show index from 表名
  9.  
  10. - 查看执行时间
  11. ;
  12. SQL...
  13. show profiles;

使用索引和不使用索引

  1. 由于索引是专门用于加速搜索而生,所以加上索引之后,查询效率会快到飞起来。
  1. # 有索引
  2. mysql> select * from tb1 where name = 'wupeiqi-888';
  3. +-----+-------------+---------------------+----------------------------------+---------------------+
  4. | nid | name | email | radom | ctime |
  5. +-----+-------------+---------------------+----------------------------------+---------------------+
  6. :: |
  7. +-----+-------------+---------------------+----------------------------------+---------------------+
  8. row in set (0.00 sec)
  9.  
  10. # 无索引
  11. mysql> select * from tb1 where email = 'wupeiqi888@live.com';
  12. +-----+-------------+---------------------+----------------------------------+---------------------+
  13. | nid | name | email | radom | ctime |
  14. +-----+-------------+---------------------+----------------------------------+---------------------+
  15. :: |
  16. +-----+-------------+---------------------+----------------------------------+---------------------+
  17. row in set (1.23 sec)

正确使用索引

数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。

即使建立索引,索引也不会生效:

  1. - like '%xx'
  2. select * from tb1 where name like '%cn';
  3. - 使用函数
  4. select * from tb1 where reverse(name) = 'wupeiqi';
  5. - or
  6. or email = 'seven@live.com';
  7. 特别的:当or条件中有未建立索引的列才失效,以下会走索引
  8. or name = 'seven';
  9. or email = 'seven@live.com' and name = 'alex'
  10. - 类型不一致
  11. 如果列是字符串类型,传入条件是必须用引号引起来,不然...
  12. ;
  13. - !=
  14. select * from tb1 where name != 'alex'
  15. 特别的:如果是主键,则还是会走索引
  16.  
  17. - >
  18. select * from tb1 where name > 'alex'
  19. 特别的:如果是主键或索引是整数类型,则还是会走索引
  20.  
  21. - order by
  22. select email from tb1 order by name desc;
  23. 当根据索引排序时候,选择的映射如果不是索引,则不走索引
  24. 特别的:如果对主键排序,则还是走索引:
  25. select * from tb1 order by nid desc;
  26.  
  27. - 组合索引最左前缀
  28. 如果组合索引为:(name,email)
  29. name and email -- 使用索引
  30. name -- 使用索引
  31. email -- 不使用索引

其他注意事项

  1. - 避免使用select *
  2. )或count(列) 代替 count(*)
  3. - 创建表时尽量时 char 代替 varchar
  4. - 表的字段顺序固定长度的字段优先
  5. - 组合索引代替多个单列索引(经常使用多个条件查询时)
  6. - 尽量使用短索引
  7. - 使用连接(JOIN)来代替子查询(Sub-Queries)
  8. - 连表时注意条件类型需一致
  9. - 索引散列值(重复少)不适合建索引,例:性别不适合

limit分页

无论是否有索引,limit分页是一个值得关注的问题

  1. 每页显示10条:
  2. 当前
  3.  
  4. 倒序:
  5.  
  6. 下一页:
  7.  
  8. select
  9. *
  10. from
  11. tb1
  12. where
  13. nid )
  14. order by
  15. nid desc
  16. limit ;
  17.  
  18. select
  19. *
  20. from
  21. tb1
  22. where
  23. nid ) A )
  24. order by
  25. nid desc
  26. limit ;
  27.  
  28. 上一页:
  29.  
  30. select
  31. *
  32. from
  33. tb1
  34. where
  35. nid )
  36. order by
  37. nid desc
  38. limit ;
  39.  
  40. select
  41. *
  42. from
  43. tb1
  44. where
  45. nid ) A
  46.  
  47. )
  48. order by
  49. nid desc
  50. limit ;

执行计划

explain + 查询SQL – 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化

  1. mysql> explain select * from tb2;
  2. +----+-------------+-------+------+---------------+------+---------+------+------+-------+
  3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  4. +----+-------------+-------+------+---------------+------+---------+------+------+-------+
  5. | NULL |
  6. +----+-------------+-------+------+---------------+------+---------+------+------+-------+
  7. row in set (0.00 sec)

执行计划

  1. id
  2. 查询顺序标识
  3. 如:mysql) as B;
  4. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  5. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  6. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  7. | NULL |
  8. | Using where |
  9. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  10. 特别的:如果使用union连接气值可能为null
  11.  
  12. select_type
  13. 查询类型
  14. SIMPLE 简单查询
  15. PRIMARY 最外层查询
  16. SUBQUERY 映射为子查询
  17. DERIVED 子查询
  18. UNION 联合
  19. UNION RESULT 使用联合的结果
  20. ...
  21. table
  22. 正在访问的表名
  23.  
  24. type
  25. 查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
  26. ALL 全表扫描,对于数据表从头到尾找一遍
  27. select * from tb1;
  28. 特别的:如果有limit限制,则找到之后就不在继续向下扫描
  29. select * from tb1 where email = 'seven@live.com'
  30. ;
  31. 虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
  32.  
  33. INDEX 全索引扫描,对索引从头到尾找一遍
  34. select nid from tb1;
  35.  
  36. RANGE 对索引列进行范围查找
  37. select * from tb1 where name < 'alex';
  38. PS:
  39. between and
  40. in
  41. > >= < <= 操作
  42. 注意:!= > 符号
  43.  
  44. INDEX_MERGE 合并索引,使用多个单列索引搜索
  45. ,,);
  46.  
  47. REF 根据索引查找一个或多个值
  48. select * from tb1 where name = 'seven';
  49.  
  50. EQ_REF 连接时使用primary key unique类型
  51. select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
  52.  
  53. CONST 常量
  54. 表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
  55. ;
  56.  
  57. SYSTEM 系统
  58. 表仅有一行(=系统表)。这是const联接类型的一个特例。
  59. ) as A;
  60. possible_keys
  61. 可能使用的索引
  62.  
  63. key
  64. 真实使用的
  65.  
  66. key_len
  67. MySQL中使用索引字节长度
  68.  
  69. rows
  70. mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
  71.  
  72. extra
  73. 该列包含MySQL解决查询的详细信息
  74. Using index
  75. 此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
  76. Using where
  77. 这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
  78. Using temporary
  79. 这意味着mysql在对查询结果排序时会使用一个临时表。
  80. Using filesort
  81. 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
  82. Range checked for each record(index map: N)”
  83. 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。

慢日志查询

a、配置MySQL自动记录慢日志

  1. slow_query_log = OFF 是否开启慢日志记录
  2. long_query_time 时间限制,超过此时间,则记录
  3. slow_query_log_file = /usr/slow.log 日志文件
  4. log_queries_not_using_indexes = OFF 为使用索引的搜索是否记录

注:查看当前配置信息:
       show variables like ‘%query%’
     修改当前配置:
    set global 变量名 = 值

b、查看MySQL慢日志

mysqldumpslow -s at -a  /usr/local/var/mysql/MacBook-Pro-3-slow.log

参数详解

  1. """
  2. --verbose 版本
  3. --debug 调试
  4. --help 帮助
  5.  
  6. -v 版本
  7. -d 调试模式
  8. -s ORDER 排序方式
  9. what to sort by (al, at, ar, c, l, r, t), 'at' is default
  10. al: average lock time
  11. ar: average rows sent
  12. at: average query time
  13. c: count
  14. l: lock time
  15. r: rows sent
  16. t: query time
  17. -r 反转顺序,默认文件倒序拍。reverse the sort order (largest last instead of first)
  18. -t NUM 显示前N条just show the top n queries
  19. -a 不要将SQL中数字转换成N,字符串转换成S。don't abstract all numbers to N and strings to 'S'
  20. -n NUM abstract numbers with at least n digits within names
  21. -g PATTERN 正则匹配;grep: only consider stmts that include this string
  22. -h HOSTNAME mysql机器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),
  23. default is '*', i.e. match all
  24. -i NAME name of server instance (if using mysql.server startup script)
  25. -l 总时间中不减去锁定时间;don't subtract lock time from total time
  26. """

最全面的 MySQL 索引详解的更多相关文章

  1. 【详细解析】MySQL索引详解( 索引概念、6大索引类型、key 和 index 的区别、其他索引方式)

    [详细解析]MySQL索引详解( 索引概念.6大索引类型.key 和 index 的区别.其他索引方式) MySQL索引的概念: 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分 ...

  2. 最全面的Android Webview详解

    转自:最全面的Android Webview详解 前言 现在很多App里都内置了Web网页(Hyprid App),比如说很多电商平台,淘宝.京东.聚划算等等,如下图  那么这种该如何实现呢?其实这是 ...

  3. MySQL 索引详解大全

    什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2. 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结 ...

  4. mysql索引详解(转)

    什么是索引 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面的 ...

  5. [转]mysql索引详解

    转自:http://www.cnblogs.com/ggjucheng/archive/2012/11/04/2754128.html 什么是索引 索引用来快速地寻找那些具有特定值的记录,所有MySQ ...

  6. Mysql索引详解及优化(key和index区别)

    MySQL索引的概念    索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库 ...

  7. 11、mysql索引详解

    1.索引介绍: 2.建立索引的方法: 注意:索引名称不要相同: (1)在建表的时候,可以增加主键索引的语句如下: 1)例一: create table student1 ( id int(4) not ...

  8. mysql 索引 详解

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytabl ...

  9. MySQL 索引详解

    本文介绍了数据库索引,及其优.缺点.针对MySQL索引的特点.应用进行了详细的描述.分析了如何避免MySQL无法使用,如何使用EXPLAIN分析查询语句,如何优化MySQL索引的应用. 索引是一种特殊 ...

随机推荐

  1. kail新手安装

    Kali Linux下载链接:http://mirrors.ustc.edu.cn/kali-images/kali-2.0/ (ps:建议用国内镜像源下载,速度有保证) Kali Linux安装之后 ...

  2. NDK(18)使用C++ STL

    1,在Application.mk 中使用 APP_STL := stlport_static 等. APP_ABI := x86 armeabi APP_PLATFORM := android-15 ...

  3. 【HDOJ】5632 Rikka with Array

    1. 题目描述$A[i]$表示二级制表示的$i$的数字之和.求$1 \le i < j \le n$并且$A[i]>A[j]$的$(i,j)$的总对数. 2. 基本思路$n \le 10^ ...

  4. [POJ2398]Toy Storage(计算几何,二分,判断点在线段的哪一侧)

    题目链接:http://poj.org/problem?id=2398 思路RT,和POJ2318一样,就是需要排序,输出也不一样.手工画一下就明白了.注意叉乘的时候a×b是判断a在b的顺时针还是逆时 ...

  5. 通俗易懂的讲解iphone视图控制器的生命周期

    IOS 视图控制器的生命周期非常非常重要,所以我有必要写个文章来和大家一起探讨问题. 今天在学习视图控制器的生命周期,也看了一下网上的一些资料,但总觉得不是那么好理解,首先我们来看一张图: 先粗略讲一 ...

  6. 面试题_125_to_133_Java 面试中其他各式各样的问题

    这部分包含 Java 中关于 XML 的面试题,JDBC 面试题,正则表达式面试题,Java 错误和异常及序列化面试题 125)嵌套静态类与顶级类有什么区别?(答案)一个公共的顶级类的源文件名称与类名 ...

  7. mkdir -p

    git bash 或 mac terminal 我们可以使用 mkdir 命令来创建文件夹. 当前目录创建多个文件夹: $ mkdir a b c 会创建 a .b.c 三个文件夹 但是有时候我们需要 ...

  8. hdu 4941 Magical Forest ( 双重map )

    题目链接 题意: 有一个n*m的田地,里边有k棵树,每棵树的位置为(xi,yi),含有能量值ci.之后又q个询问,分三种; 1)1 a b,将a行和b行交换 2)2 a b,将a列和b列交换 3)3 ...

  9. ADODB.Connection 错误 '800a0e7a' 未找到提供程序。该程序可能未正确安装。解决方法!

    [问题描述]调试基于ACCESS+ASP的网站程序的时候,遇到如下错误: ADODB.Connection 错误 '800a0e7a' 未找到提供程序.该程序可能未正确安装. /Inc/Functio ...

  10. 關於NPOI的一點補充和示例

    最近看到很多人分享NPOI的用法. 但是很多都不是完整示例或者並沒有實戰效果. 剛好最近有個VB.NET的項目有升級原有的oledb select sheet$的做法. 很明顯,NPOI有更好的穩定性 ...