最近困扰自己很久的膝盖积液手术终于做完,在家养伤,逛技术博客看到easyswoole开发组成员仙士可博客有关mysql索引方面的知识,自己打算重温下。

正常业务起步数据表数据量较少,不用考虑使用索引,当后期累积的数据数量非常可观时,使用索引是提升查询的一条途径,其他的像表分区,分库分表等等。

【索引创建】

索引的创建需要考虑被创建索引的字段区分度,比如一张表里面有渠道channel,渠道可期种类不超过3种,win系,安卓系,iOS系,而数据表数据量有一百万,平均下来每个渠道各是1/3也就是33万数据,这样的数据量就是否基于channel 索引区别都不会太大。

但是如果基于date字段做索引,如20200114,一年一百万,除以365天,平均下来每天300条数据。这个区分度是相当大。

同样的索引使用 33w数据查询显然效率低于300条数据。

索引可以加快mysql服务查询速度,但不是索引越多越好,因为insert或update的同时存放索引的文件也需要进行更新,会影响数据插入更新的速度,如果对数据实时性有要求的,无疑会受较大影响。

这里挑两种情况演示给大家看下。

【索引失效】

一. 单字段索引:字段是string类型,传入int类型参数。

MySQL [test_db]> show create table test_users\G;
*************************** 1. row ***************************
Table: test_users
Create Table: CREATE TABLE `test_users` (
`uid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` char(15) NOT NULL,
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` char(11) NOT NULL DEFAULT '',
PRIMARY KEY (`uid`),
KEY `testindex` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1306001 DEFAULT CHARSET=utf8mb4
1 row in set (0.04 sec) ERROR: No query specified #开启profile
MySQL [test_db]> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.03 sec)
#开始查询
MySQL [test_db]> select * from test_users where user_id='';
Empty set (0.04 sec) MySQL [test_db]> select * from test_users where user_id=97737;
Empty set (0.14 sec) #关闭profile
MySQL [test_db]> set profiling=0;
Query OK, 0 rows affected, 1 warning (0.03 sec) #explain查看一下
MySQL [test_db]> explain select * from test_users where user_id='' ;
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | test_users | NULL | ref | testindex | testindex | 44 | const | 1 | 100.00 | NULL |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.05 sec) MySQL [test_db]> explain select * from test_users where user_id=97737;
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | test_users | NULL | ALL | testindex | NULL | NULL | NULL | 306078 | 10.00 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 3 warnings (0.04 sec)
#以上可见当使用user_id匹配int类型时,key=null,索引失效
#再看profile分析结果,可见加单引号比起不加单引号快上10倍左右
MySQL [test_db]> show profiles;
+----------+------------+-------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------------+
| 1 | 0.01234100 | select * from test_users where user_id='' |
| 2 | 0.10183000 | select * from test_users where user_id=97737 |
+----------+------------+-------------------------------------------------+
2 rows in set, 1 warning (0.04 sec) #再看更详细的分析
MySQL [test_db]> show profile cpu,block io,swaps for query 1;
+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting | 0.000088 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| checking permissions | 0.000006 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Opening tables | 0.000021 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| init | 0.003386 | 0.001000 | 0.000000 | 240 | 0 | 0 |
| System lock | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| optimizing | 0.000011 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| statistics | 0.007039 | 0.000000 | 0.000000 | 592 | 0 | 0 |
| preparing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| executing | 0.000003 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Sending data | 0.001661 | 0.000000 | 0.000000 | 176 | 0 | 0 |
| end | 0.000008 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| query end | 0.000011 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| closing tables | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| freeing items | 0.000044 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| cleaning up | 0.000003 | 0.000000 | 0.000000 | 0 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+
15 rows in set, 1 warning (0.03 sec) MySQL [test_db]> show profile cpu,block io,swaps for query 2;
+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting | 0.000081 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| checking permissions | 0.000006 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Opening tables | 0.000022 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| init | 0.002129 | 0.000000 | 0.000000 | 72 | 0 | 0 |
| System lock | 0.000010 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| optimizing | 0.000009 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| statistics | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| preparing | 0.000014 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| executing | 0.000002 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Sending data | 0.099419 | 0.092986 | 0.000000 | 400 | 0 | 0 |
| end | 0.000016 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| query end | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| closing tables | 0.000026 | 0.001000 | 0.000000 | 0 | 0 | 0 |
| freeing items | 0.000054 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| cleaning up | 0.000003 | 0.000000 | 0.000000 | 0 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+
15 rows in set, 1 warning (0.04 sec)
#通过对比可以发现主要耗时在sending data,而其他地方相差不大
#mysql官网对sending data对解释
#Sending data:The thread is reading and processing rows for a SELECT statement, and sending data to the client.
#Because operations occurring during this state tend to perform large amounts of disk access (reads), it is often the longest-running state over the lifetime of a given query.
#大意即是:线程正在为一个select语句读取和处理行,并且发送数据到客户端。因为这期间操作倾向于大量的磁盘访问(读取),所以这常是整个查询周期中运行时间最长的阶段。 

未完待续,下一篇讲int类型,传入string类型参数有什么不一样...

mysql索引创建和使用细节的更多相关文章

  1. mysql索引创建和使用细节(二)

    上篇粗略记录当mysql字段类型是string,传入int类型参数后失效当问题. 现在测试下mysql字段是int类型,传参string类型会发生什么. 题外话,最近膝盖手术后还在家养伤中,只怪自己以 ...

  2. 索引-mysql索引创建、查看、删除及使用示例

    mysql索引创建.查看.删除及使用示例 1.创建索引: ALTER TABLE用来创建普通索引.UNIQUE索引或PRIMARY KEY索引. ALTER TABLE table_name ADD ...

  3. Database基础(二):MySQL索引创建与删除、 MySQL存储引擎的配置

    一.MySQL索引创建与删除 目标: 本案例要求熟悉MySQL索引的类型及操作方法,主要练习以下任务: 普通索引.唯一索引.主键索引的创建/删除 自增主键索引的创建/删除 建立员工表yg.工资表gz, ...

  4. MySQl索引创建

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

  5. Mysql索引创建及删除

    1.索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的My ...

  6. mysql索引 ->创建索引、修改索引、删除索引的命令语句

    查看表中已经存在 index:show index from table_name; 创建和删除索引索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER ...

  7. MYSQL 索引创建与使用

    可能用到索引的地方: where 子句,order by,group by 不需要创建索引的情况: 1. 表比较小 2.赋值有限的列(枚举),不要创建索引.创建的索引返回的行越少越好,此时区分度大. ...

  8. mysql索引创建&查看&删除

    1.索引作用 在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍. 例如,有 ...

  9. Mysql索引(究极无敌细节版)

    参考了: https://www.jianshu.com/p/ace3cd6526c4 推荐up主https://space.bilibili.com/377905911 推荐书籍<mysql是 ...

随机推荐

  1. PyTorch之前向传播函数自动调用forward

    参考:1. pytorch学习笔记(九):PyTorch结构介绍 2.pytorch学习笔记(七):pytorch hook 和 关于pytorch backward过程的理解 3.Pytorch入门 ...

  2. 洛谷P2486 [SDOI2011]染色 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2486 首先这是一道树链剖分+线段树的题. 线段树部分和 codedecision P1112 区间连续段 一模一样,所以我们 ...

  3. JS精度问题,解决方案 math.js

    JS精度问题    Vue中使用 解决方案 math.js npm install mathjs import { create, all } from 'mathjs' const config = ...

  4. Mule自带例子之flight-reservation

    1 配置效果图 2 应用的配置文件 <?xml version="1.0" encoding="UTF-8"?> <mule xmlns:sc ...

  5. js 制作分页

    如图所示 在html中调用方法 getpage(7, 1, 1, 'URL') 1.page.js文件 代码 function getpage(count, countPage, pageIndex, ...

  6. 在Vue 中调用数据出现属性不存在的问题

    这已经是我在调用数据时趟过几次的坑了,索性记录下来防止后面再犯: 一般我们请求数据来渲染一个页面的时候,请求下来的数据基本上都是数组或是对象,再通过列表循环和插值表达式渲染的页面:在data 中提前声 ...

  7. C# json 转 xml 字符串

    本文告诉大家如何将 json 转 xml 或将 xml 转 json 字符串 首先需要安装 Newtonsoft.Json 库,打开 VisualStudio 2019 新建一个 dotnet cor ...

  8. CF1055F Tree and XOR

    CF1055F Tree and XOR 就是选择两个数找第k大对儿 第k大?二分+trie上验证 O(nlognlogn) 直接按位贪心 维护可能的决策点(a,b)表示可能答案的对儿在a和b的子树中 ...

  9. 解决 npm run dev b报错 “'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件。”

    摘自:https://www.cnblogs.com/laraLee/p/9174383.html 前提: 电脑已经安装了nodeJS和npm,  项目是直接下载的zip包. 在项目目录下运行“npm ...

  10. linux /proc 接口和共享中断

    在系统中安装共享处理者不影响 /proc/stat, 它甚至不知道处理者. 但是, /proc/interrupts 稍稍变化. 所有同一个中断号的安装的处理者出现在 /proc/interrupts ...