索引相关命令

- 查看表结构

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. [React] 12 - Redux: async & middleware

    Ref: Redux 入门教程(二):中间件与异步操作 这里只是简单地了解中间件的概念,对于异步,貌似之后要讲的saga更胜一筹. reducer计算新状态的策略: Action 发出以后,Reduc ...

  2. 使用gdbserver远程调试

    使用gdbserver远程调试   1.默认crosstool交叉编译器没有自带gdbserver,需要自行编译 到GNU官方FTP下载,目前最新版的是gdb-6.7.1下载地址:http://ftp ...

  3. Erlang的crypto模块与最新的openssl动态链接库不兼容的问题与解决方案

    在2014新年伊始,增买了一台阿里云服务器,装的系统是CentOS 6.3 64位,装完Erlang后,出现了下面的情况: ./configure --without-javac --with-ssl ...

  4. SQL Server2008 删除登录记录

    SQL Server Management Studio登陆窗口  清空这些多余的登陆名   主要是删除SqlStudio.bin文件   WinXP:    C:\Documents and Set ...

  5. windows 开启热点的命令行工具

    hotspot.bat @echo off @echo. setlocal enabledelayedexpansion if "%1" == "set" ( ...

  6. Docker学习之——Node.js+MongoDB+Nginx环境搭建(一)

    最近在学习Node.js相关知识,在环境搭建上耗费了不少功夫,故此把这个过程写下来同大家分享一下,今天我先来介绍一下Docker,有很多人都写过相关知识,还有一些教程,在此我只想写一下,我的学习过程中 ...

  7. 新版谷歌浏览器怎么查找和改变编码格式 IT开发人员谷歌的编码格式

    解决方法在最下面,还有可下载的安装包 今天,无意中在解决一个乱码问题,后台是有过判断解决兼容性问题,但是有个别电脑还是有乱码问题,就去想改变下前台的编码格式,突然发现一向好用的谷歌,居然找不到编码格式 ...

  8. MPD软件工作坊上海站本周末在上海举行

    本周末(5月26日至27日)由麦思博(msup)主办的第39届MPD软件工作坊即将在上海虹桥会议中心举行.本届MPD将继续围绕软件研发领域,邀请了21位技术大咖,从产品运营.团队管理.架构技术.自动化 ...

  9. DACLs and ACEs

    [Windows]Windows的访问控制模型 - Zplutor - 博客园 https://www.cnblogs.com/zplutor/archive/2010/01/05/1639892.h ...

  10. [daily][archlinux][btrfs][mysql] 在btrfs上使用mariadb

    在btrfs上使用mariadb的时候,需要注意关闭btrfs的Copy on Write (/var/lib/mysql目录) 如下: ┬─[tong@T7:~/Data/anthropoid]─[ ...