索引相关命令

- 查看表结构

desc 表名

- 查看生成表的SQL

show create table 表名

- 查看索引

show index from 表名

- 查看sql执行时间

set profiling = 1;

SQL...

show profiles;

 

命中索引的语法

- like '%xx'

select * from tb1 where name like '%cn';
   - 使用函数
       select * from tb1 where reverse(name) = 'dddd';
   - or
         select * from tb1 where nid = 1 or email = 'seven@live.com';
         nid 是主键索引 name是普通索引 email没有索引
         特别的:当or条件中有未建立索引的列才失效,以下会走索引
         select * from tb1 where nid = 1 or name = 'seven';
         select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'aaa'
 -   类型不一致
       如果列是字符串类型,传入条件是必须用引号引起来
       select * from tb1 where name = 999;
  -   !=
       select * from tb1 where name != 'aaa'
       特别的:如果是主键,则还是会走索引
       select * from tb1 where nid != 123
   -  >
       select * from tb1 where name > 'aaa'
       特别的:如果是主键或索引是整数类型,则还是会走索引
       select * from tb1 where nid > 123
       select * from tb1 where num > 123
  - order by
      select email from tb1 order by name desc;
      当根据索引排序时候,选择的映射如果不是索引,则不走索引
      特别的:如果对主键排序,则还是走索引:
     select * from tb1 order by nid desc;

组合索引最左前缀
       如果组合索引为:(name,email)
       name and email         -- 使用索引
       name                         -- 使用索引
      email                          -- 不使用索引

索引优化建议

只要列中含有NULL值,就最好不要在此例设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引

尽量使用短索引,如果可以,应该制定一个前缀长度

对于经常在where子句使用的列,最好设置索引

对于有多个列where或者order by子句,应该建立复合索引

对于like语句,以%或者‘-’开头的不会使用索引,以%结尾会使用索引

尽量不要在列上进行运算(函数操作和表达式操作)

尽量不要使用not in和<>操作

SQL语句性能优化

查询时,能不要*就不用*,尽量写全字段名

大部分情况连接效率远大于子查询

多表连接时,尽量小表驱动大表,即小表 join 大表

在千万级分页时使用limit

对于经常使用的查询,可以开启缓存

多使用explain和profile分析查询语句

查看慢查询日志,找出执行时间长的sql语句优化

查询执行计划

MariaDB [hellodb]> explain select * from testdata limit 1000000;
+------+-------------+----------+------+---------------+------+---------+------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+------+---------+-------+
| 1 | SIMPLE | testdata | ALL | NULL | NULL | NULL | NULL | 2992881 | |
+------+-------------+----------+------+---------------+------+---------+------+---------+-------+
1 row in set (0.00 sec)

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

慢日志查询

   配置MySQL自动记录慢日志

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

  查看MySQL慢日志

mysqldumpslow -s at -a  /usr/slow.log

sql高性能分页查询

使用limit进行分页,页码越大,分页速度会越来越慢.

limit 查询数据原理:

limit 0, 10         扫描数据表前10条记录只取前10条记录

limit10, 10        扫描数据表前20条记录只取后10条记录

越往后面取数据,需要扫描的数据量会越大,效率就会越慢

优化策略:

记录当前页的最大max_id和最小min_id,减少limit扫描记录数量

- 索引表中扫:
       select * from userinfo3 where id in(select id from userinfo3 limit 200000,10)
     - 方案:
      记录当前页最大或最小ID
          1. 页面只有上一页,下一页
             # max_id
             # min_id
             下一页:
                    select * from userinfo3 where id > max_id limit 10;
            上一页:
                   select * from userinfo3 where id < min_id order by id desc limit 10;
         2. 上一页 192 193 [196] 197 198 199 下一页
                select * from userinfo3 where id in (
                    select id from (select id from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10
               )

Mysql索引详细语法的更多相关文章

  1. Mysql 索引详细解释

    MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化)  一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二. ...

  2. mysql索引详细描述与应用场景

    索引的数据结构: (1)一般是B+tree:MySql使用最频繁的一个索引数据结构,数据结构以平衡树的形式来组织,因为是树型结构,所以更适合用来处理排序,范围查找等功能. (2)Hash:Hsah索引 ...

  3. mysql索引详细介绍

    博客: https://blog.csdn.net/tongdanping/article/details/79878302#%E4%B8%89%E3%80%81%E7%B4%A2%E5%BC%95% ...

  4. 0x08 MySQL 超详细-索引原理&慢查询优化【转-多图】(重点)

    Content From——Egon's Blog http://www.cnblogs.com/linhaifeng/articles/7274563.html#top 0x01 介绍 为何要有索引 ...

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

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

  6. MySQL索引优化,explain详细讲解

    前言:这篇文章主要讲 explain 如何使用,还有 explain 各种参数概念,之后会讲优化 一.Explain 用法 模拟Mysql优化器是如何执行SQL查询语句的,从而知道Mysql是如何处理 ...

  7. 单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式

    单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式     一 表结构如下:  万行 CREATE TABLE t_audit_operate_log (  Fid b ...

  8. MySQL索引语法+使用场景

    MySQL索引语法 建表时添加索引 建表同时建立单索引 CREATE TABLE t_user1(id INT , userName VARCHAR(20), PASSWORD VARCHAR(20) ...

  9. mysql索引语法及示例

    注:本篇文章是对菜鸟教程中的mysql索引(http://www.runoob.com/mysql/mysql-index.html)的翻译版本:添加了示例,便于理解: 索引分单列索引和组合索引.单列 ...

随机推荐

  1. 5 -- Hibernate的基本用法 --5 1 持久化类的要求

    1.  提供一个无参数的构造器:所有的持久化类都应该提供一个无参数的构造器,这个构造器可以不采用public访问控制符.只要提供了无参数的构造器,Hibernate就可以使用Constructor.n ...

  2. 【GIS】Vue、Leaflet、highlightmarker、bouncemarker

    感谢: https://github.com/brandonxiang/leaflet.marker.highlight https://github.com/maximeh/leaflet.boun ...

  3. mem 0908

    taglib http://blog.csdn.net/zyujie/article/details/8735730 dozer: Dozer可以在JavaBean到JavaBean之间进行递归数据复 ...

  4. 【netcore基础】MVC API接口权限控制Attribute

    效果: 通过Attribute来简单控制某个方法的访问权限 例如: 下面api只能角色id是[001,002,999]的登录用户才能访问 /// <summary> /// 管理用户列表 ...

  5. VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面,直接使用自带远程工具)

    本文主要是讲解如果理由VNC实现Windows远程访问Ubuntu 16.04,其实网上有很多类似教程,但是很多需要安装第三方桌面(xfce桌面等等),而且很多人不太喜欢安装第三方桌面,很多人像笔者一 ...

  6. 编译你的第一个Java虚拟机--Centos 7 编译openJdk1.7源码

    一.前言 最近在看<深入java虚拟机>,看完后,打算自己实际编译一个jvm出来看看,实践一下. 书上提到了Oracle JDK和OpenJdk的关系,Oracle Jdk7 和OpenJ ...

  7. jenkins实战(二):构建自由风格的maven项目

    本系列打算全面介绍jenkins的常规使用,这是第二篇,之前的文章在: jenkins实战(一):war安装及插件安装 一.新建项目 1.新建项目 此处我们打算新建自由风格项目,见下图. 值得注意的是 ...

  8. PHP链接MySQL,查询数据库内容,删除数据库内容。。。记住链接公式!!!

    //扩展类叫MySQLi MySQL是数据库,MySQLi是扩展 Id地址本地网络服务器的地址localhost 如果想链接别人的输入他的服务器id地址. //root代表的是数据库名, //poss ...

  9. - Fractal(3.4.1)

    C - Fractal(3.4.1) Time Limit:1000MS    Memory Limit:30000KB    64bit IO Format:%I64d & %I64u Su ...

  10. SVN如何忽略dll文件和bin目录

    一般来说,编译之后的结果文件都会放在bin目录下.用svn做代码管理服务器的时候,肯定不希望编译的结果文件也签入进去,因此需要在客户端配置. 在checkout目录下,在svn的子菜单中 Proper ...