Mysql索引详细语法
索引相关命令
- 查看表结构
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索引详细语法的更多相关文章
- Mysql 索引详细解释
MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化) 一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二. ...
- mysql索引详细描述与应用场景
索引的数据结构: (1)一般是B+tree:MySql使用最频繁的一个索引数据结构,数据结构以平衡树的形式来组织,因为是树型结构,所以更适合用来处理排序,范围查找等功能. (2)Hash:Hsah索引 ...
- mysql索引详细介绍
博客: https://blog.csdn.net/tongdanping/article/details/79878302#%E4%B8%89%E3%80%81%E7%B4%A2%E5%BC%95% ...
- 0x08 MySQL 超详细-索引原理&慢查询优化【转-多图】(重点)
Content From——Egon's Blog http://www.cnblogs.com/linhaifeng/articles/7274563.html#top 0x01 介绍 为何要有索引 ...
- 【详细解析】MySQL索引详解( 索引概念、6大索引类型、key 和 index 的区别、其他索引方式)
[详细解析]MySQL索引详解( 索引概念.6大索引类型.key 和 index 的区别.其他索引方式) MySQL索引的概念: 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分 ...
- MySQL索引优化,explain详细讲解
前言:这篇文章主要讲 explain 如何使用,还有 explain 各种参数概念,之后会讲优化 一.Explain 用法 模拟Mysql优化器是如何执行SQL查询语句的,从而知道Mysql是如何处理 ...
- 单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式
单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式 一 表结构如下: 万行 CREATE TABLE t_audit_operate_log ( Fid b ...
- MySQL索引语法+使用场景
MySQL索引语法 建表时添加索引 建表同时建立单索引 CREATE TABLE t_user1(id INT , userName VARCHAR(20), PASSWORD VARCHAR(20) ...
- mysql索引语法及示例
注:本篇文章是对菜鸟教程中的mysql索引(http://www.runoob.com/mysql/mysql-index.html)的翻译版本:添加了示例,便于理解: 索引分单列索引和组合索引.单列 ...
随机推荐
- [React] 12 - Redux: async & middleware
Ref: Redux 入门教程(二):中间件与异步操作 这里只是简单地了解中间件的概念,对于异步,貌似之后要讲的saga更胜一筹. reducer计算新状态的策略: Action 发出以后,Reduc ...
- 使用gdbserver远程调试
使用gdbserver远程调试 1.默认crosstool交叉编译器没有自带gdbserver,需要自行编译 到GNU官方FTP下载,目前最新版的是gdb-6.7.1下载地址:http://ftp ...
- Erlang的crypto模块与最新的openssl动态链接库不兼容的问题与解决方案
在2014新年伊始,增买了一台阿里云服务器,装的系统是CentOS 6.3 64位,装完Erlang后,出现了下面的情况: ./configure --without-javac --with-ssl ...
- SQL Server2008 删除登录记录
SQL Server Management Studio登陆窗口 清空这些多余的登陆名 主要是删除SqlStudio.bin文件 WinXP: C:\Documents and Set ...
- windows 开启热点的命令行工具
hotspot.bat @echo off @echo. setlocal enabledelayedexpansion if "%1" == "set" ( ...
- Docker学习之——Node.js+MongoDB+Nginx环境搭建(一)
最近在学习Node.js相关知识,在环境搭建上耗费了不少功夫,故此把这个过程写下来同大家分享一下,今天我先来介绍一下Docker,有很多人都写过相关知识,还有一些教程,在此我只想写一下,我的学习过程中 ...
- 新版谷歌浏览器怎么查找和改变编码格式 IT开发人员谷歌的编码格式
解决方法在最下面,还有可下载的安装包 今天,无意中在解决一个乱码问题,后台是有过判断解决兼容性问题,但是有个别电脑还是有乱码问题,就去想改变下前台的编码格式,突然发现一向好用的谷歌,居然找不到编码格式 ...
- MPD软件工作坊上海站本周末在上海举行
本周末(5月26日至27日)由麦思博(msup)主办的第39届MPD软件工作坊即将在上海虹桥会议中心举行.本届MPD将继续围绕软件研发领域,邀请了21位技术大咖,从产品运营.团队管理.架构技术.自动化 ...
- DACLs and ACEs
[Windows]Windows的访问控制模型 - Zplutor - 博客园 https://www.cnblogs.com/zplutor/archive/2010/01/05/1639892.h ...
- [daily][archlinux][btrfs][mysql] 在btrfs上使用mariadb
在btrfs上使用mariadb的时候,需要注意关闭btrfs的Copy on Write (/var/lib/mysql目录) 如下: ┬─[tong@T7:~/Data/anthropoid]─[ ...