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

上篇粗略记录当mysql字段类型是string,传入int类型参数后失效当问题。

现在测试下mysql字段是int类型,传参string类型会发生什么。

题外话,最近膝盖手术后还在家养伤中,只怪自己以前骑车不注意休息保养,经常长途骑行出去玩,把膝盖骑费了(抽取积液+切除膝盖囊肿手术),搞得现在哪都去不了,已经一周没下楼走走。

【索引失效】

二. 单字段索引:字段是INT类型,传入string类型参数

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` int(11) unsigned NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`uid`),
  KEY `testindex` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1306001 DEFAULT CHARSET=utf8mb4
1 row in set (0.05 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 = ‘930324‘;
Empty set (0.03 sec)

MySQL [test_db]> select * from test_users where user_id = 899242;
Empty set (0.03 sec)

 MySQL [test_db]> set profiling=0;
  Query OK, 0 rows affected, 1 warning (0.04 sec)

MySQL [test_db]> show profiles;
+----------+------------+---------------------------------------------------+
| Query_ID | Duration   | Query                                             |
+----------+------------+---------------------------------------------------+
|        1 | 0.00034000 | select * from test_users where user_id = ‘930324‘ |
|        2 | 0.00034850 | select * from test_users where user_id = 899242   |
+----------+------------+---------------------------------------------------+
2 rows in set, 1 warning (0.04 sec)
#可以看到两种查询耗时基本持平
MySQL [test_db]> explain select * from test_users where user_id = 899242;
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_users | NULL       | ref  | testindex     | testindex | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.03 sec)

MySQL [test_db]> explain select * from test_users where user_id = ‘899242‘;
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_users | NULL       | ref  | testindex     | testindex | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.04 sec)
#再用explain分析下,可见两种查询都是key=testindex

上面针对的都是单字段索引,现在我们使用组合索引,对比下会有什么不一样。

三. 组合索引

MySQL [test_db]> show create table test_log\G;
*************************** 1. row ***************************
       Table: test_log
Create Table: CREATE TABLE `test_log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `log_id` int(11) unsigned NOT NULL DEFAULT ‘0‘,
  `rand_name` char(15) NOT NULL,
  `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `country` varchar(50) NOT NULL DEFAULT ‘‘,
  `short_country_name` char(5) NOT NULL DEFAULT ‘‘,
  PRIMARY KEY (`id`),
  KEY `c` (`country`),
  KEY `log` (`log_id`,`rand_name`,`country`)
) ENGINE=InnoDB AUTO_INCREMENT=6601004 DEFAULT CHARSET=utf8mb4
1 row in set (0.04 sec)

ERROR: No query specified

MySQL [test_db]> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = ‘66423‘;
Empty set (0.04 sec)

MySQL [test_db]> select * from test_log where log_id = 987371;
+--------+--------+--------------+---------------------+--------------------+--------------------+
| id     | log_id | rand_name    | created_time        | country            | short_country_name |
+--------+--------+--------------+---------------------+--------------------+--------------------+
| 948373 | 987371 | 1ae53be9c1df | 2020-01-16 12:01:09 | 中国澳门特区       | MO                 |
+--------+--------+--------------+---------------------+--------------------+--------------------+
1 row in set (0.04 sec)

MySQL [test_db]> set profiling =0;
Query OK, 0 rows affected, 1 warning (0.03 sec)

MySQL [test_db]> show profiles;
+----------+------------+---------------------------------------------------+
| Query_ID | Duration   | Query                                             |
+----------+------------+---------------------------------------------------+
|        1 | 0.00034000 | select * from test_users where user_id = ‘930324‘ |
|        2 | 0.00034850 | select * from test_users where user_id = 899242   |
|        3 | 0.00464450 | select * from test_log where log_id = ‘66423‘     |
|        4 | 0.01399875 | select * from test_log where log_id = 987371      |
+----------+------------+---------------------------------------------------+
4 rows in set, 1 warning (0.03 sec)

#有没有发现什么不对劲的地方?
#没错 该组合索引里面 log_id是int类型,string类型参数比int类型参数快,到底哪里出问题?

#explain分析下
MySQL [test_db]> explain select * from test_log where log_id = ‘66423‘;
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_log | NULL       | ref  | log           | log  | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.05 sec)

MySQL [test_db]> explain select * from test_log where log_id = 987371;
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_log | NULL       | ref  | log           | log  | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.03 sec)

#explain得到的结果都是一模一样!!! 那为什么有快慢之分,为了方便数据比较,我们重连mysql连接l。

Database changed
MySQL [test_db]> set profiling = 1;
Query OK, 0 rows affected, 1 warning (0.04 sec)

MySQL [test_db]> select * from test_log where log_id = ‘5990180‘;
+---------+---------+--------------+---------------------+--------------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country            | short_country_name |
+---------+---------+--------------+---------------------+--------------------+--------------------+
| 5941183 | 5990180 | 970eb4c2f8e8 | 2020-01-17 13:20:37 | 吉尔吉斯斯坦       | KG                 |
+---------+---------+--------------+---------------------+--------------------+--------------------+
1 row in set (0.05 sec)

MySQL [test_db]> select * from test_log where log_id = ‘2999080‘;
+---------+---------+--------------+---------------------+-----------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country         | short_country_name |
+---------+---------+--------------+---------------------+-----------------+--------------------+
| 2950083 | 2999080 | 805c2b1fbab1 | 2020-01-17 13:02:40 | 所罗门群岛      | Sb                 |
+---------+---------+--------------+---------------------+-----------------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = ‘3900242‘;
+---------+---------+--------------+---------------------+-----------+--------------------+
| id      | log_id  | rand_name    | created_time        | country   | short_country_name |
+---------+---------+--------------+---------------------+-----------+--------------------+
| 3851245 | 3900242 | f19fcdd1172e | 2020-01-17 13:08:21 | 菲律宾    | PH                 |
+---------+---------+--------------+---------------------+-----------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = ‘4440242‘;
+---------+---------+--------------+---------------------+--------------------------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country                        | short_country_name |
+---------+---------+--------------+---------------------+--------------------------------+--------------------+
| 4391245 | 4440242 | fd03f30dfc3e | 2020-01-17 13:11:20 | 圣文森特和格陵纳丁斯           | VC                 |
+---------+---------+--------------+---------------------+--------------------------------+--------------------+
1 row in set (0.04 sec)

MySQL [test_db]> select * from test_log where log_id = 23440242;
Empty set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = 2344042;
+---------+---------+--------------+---------------------+--------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country      | short_country_name |
+---------+---------+--------------+---------------------+--------------+--------------------+
| 2295045 | 2344042 | bc89598c0d10 | 2020-01-17 12:58:47 | 格鲁吉亚     | GE                 |
+---------+---------+--------------+---------------------+--------------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = 5314042;
+---------+---------+--------------+---------------------+--------------------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country                  | short_country_name |
+---------+---------+--------------+---------------------+--------------------------+--------------------+
| 5265045 | 5314042 | 452e5ecf5fa5 | 2020-01-17 13:16:44 | 特立尼达和多巴哥         | TT                 |
+---------+---------+--------------+---------------------+--------------------------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = 5614092;
+---------+---------+--------------+---------------------+--------------+--------------------+
| id      | log_id  | rand_name    | created_time        | country      | short_country_name |
+---------+---------+--------------+---------------------+--------------+--------------------+
| 5565095 | 5614092 | 78adae2b40a3 | 2020-01-17 13:18:31 | 马约特岛     | YT                 |
+---------+---------+--------------+---------------------+--------------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = 5900392;
+---------+---------+--------------+---------------------+---------+--------------------+
| id      | log_id  | rand_name    | created_time        | country | short_country_name |
+---------+---------+--------------+---------------------+---------+--------------------+
| 5851395 | 5900392 | e89ccadae397 | 2020-01-17 13:20:19 | 挪威    | NO                 |
+---------+---------+--------------+---------------------+---------+--------------------+
1 row in set (0.04 sec)

MySQL [test_db]> set profiling = 0;
Query OK, 0 rows affected, 1 warning (0.03 sec)

MySQL [test_db]> show profiles;
+----------+------------+-------------------------------------------------+
| Query_ID | Duration   | Query                                           |
+----------+------------+-------------------------------------------------+
|        1 | 0.01717650 | select * from test_log where log_id = ‘5990180‘ |
|        2 | 0.00281950 | select * from test_log where log_id = ‘2999080‘ |
|        3 | 0.00167475 | select * from test_log where log_id = ‘3900242‘ |
|        4 | 0.00431675 | select * from test_log where log_id = ‘4440242‘ |
|        5 | 0.00032000 | select * from test_log where log_id = 23440242  |
|        6 | 0.00387325 | select * from test_log where log_id = 2344042   |
|        7 | 0.00461725 | select * from test_log where log_id = 5314042   |
|        8 | 0.00485450 | select * from test_log where log_id = 5614092   |
|        9 | 0.00476200 | select * from test_log where log_id = 5900392   |
+----------+------------+-------------------------------------------------+
9 rows in set, 1 warning (0.04 sec)
#通过对比发现字段为int类型是,参数是int还是string对耗时影响不大
#耗时差别不大,我们猜测一下这里mysql默认将string类型转换成int类型了
#不相信的话,我们来验证下就知道了

MySQL [test_db]> select * from test_log where log_id = ‘a666f‘;
Empty set (0.04 sec)

MySQL [test_db]> select * from test_log limit 1;
+----+--------+--------------+---------------------+--------------------------------+--------------------+
| id | log_id | rand_name    | created_time        | country                        | short_country_name |
+----+--------+--------------+---------------------+--------------------------------+--------------------+
|  1 |      1 | c4ca4238a0b9 | 2020-01-16 11:54:25 | 中立区(沙特-伊拉克间)          | NT                 |
+----+--------+--------------+---------------------+--------------------------------+--------------------+
1 row in set (0.04 sec)

MySQL [test_db]> update test_log set log_id=0 where id = 1;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MySQL [test_db]> select * from test_log where log_id = ‘a666f‘;
+----+--------+--------------+---------------------+--------------------------------+--------------------+
| id | log_id | rand_name    | created_time        | country                        | short_country_name |
+----+--------+--------------+---------------------+--------------------------------+--------------------+
|  1 |      0 | c4ca4238a0b9 | 2020-01-16 11:54:25 | 中立区(沙特-伊拉克间)          | NT                 |
+----+--------+--------------+---------------------+--------------------------------+--------------------+
1 row in set (0.03 sec)

MySQL [test_db]> select * from test_log where log_id = ‘12a1a‘;
+----+--------+--------------+---------------------+---------+--------------------+
| id | log_id | rand_name    | created_time        | country | short_country_name |
+----+--------+--------------+---------------------+---------+--------------------+
| 12 |     12 | c20ad4d76fe9 | 2020-01-16 11:54:25 | 英国    | UK                 |
+----+--------+--------------+---------------------+---------+--------------------+
1 row in set (0.04 sec)

MySQL [test_db]> select * from test_log where log_id = ‘02a1a‘;
+----+--------+--------------+---------------------+---------+--------------------+
| id | log_id | rand_name    | created_time        | country | short_country_name |
+----+--------+--------------+---------------------+---------+--------------------+
|  2 |      2 | c81e728d9d4c | 2020-01-16 11:54:25 | 中国    | CN                 |
+----+--------+--------------+---------------------+---------+--------------------+
1 row in set (0.03 sec)

原文地址:https://www.cnblogs.com/wscsq789/p/12208725.html

时间: 2024-10-11 05:02:13

mysql索引创建和使用细节(二)的相关文章

MySQl索引创建

一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面的记录数量越多,这个操作的代价就越高.如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置.如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍. 假设我们创建了一个名为people的表: CREATE TABLE people ( p

MySQL索引创建与删除,MySQL存储引擎的配置

MySQL索引创建与删除 1.1 问题 本案例要求熟悉MySQL索引的类型及操作方法,主要练习以下任务: 普通索引.唯一索引.主键索引的创建/删除 自增主键索引的创建/删除 建立员工表yg.工资表gz,数据内容如表-1.表-2所示,设置外键实现同步更新与同步删除 表-1 员工表yg的数据 表-2 工资表gz的数据 1.2 步骤 实现此案例需要按照如下步骤进行. 步骤一:索引的创建与删除 创建表的时候指定INDEX索引字段 创建库home: mysql> create database home;

MySQL索引创建、删除、查看

主键索引 ??PRIMARY KEY索引仅是一个具有名称PRIMARY的UNIQUE索引.这表示一个表只能包含一个PRIMARY KEY,因为一个表中不可能具有两个同名的索引. ALTER TABLE 'tablename' ADD PRIMARY KEY("column"); 普通索引 直接创建索引:CREATE INDEX 'indexname' ON 'tablename'('column'('account')); 修改表结构的方式创建索引:ALTER TABLE 'table

mysql索引原理及优化(二)

索引原理分析:数据结构 索引是最常见的慢查询优化方式其是一种优化查询的数据结构,MySql中的索引是用B+树实现,而B+树就是一种数据结构,可以优化查询速度,可以利用索引快速查找数据,优化查询. 可以提高查询速度的数据结构:哈希表.完全平衡二叉树.B树.B+树等等. 哈希:select* from sanguo where name>'周瑜     哈希表的特点是可以快速的精确查询,但是不支持范围查询.完全平衡二叉树:对于数据量大情况,它相比于哈希或者B树.B+树需要查找次数更多.B树:比完全平

mysql 索引创建规则

1.表的主键.外键必须有索引:2.数据量超过300的表应该有索引: 3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特别是大表的字段,应该建立索引: 5.索引应该建在选择性高的字段上: 6.索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引: 7.复合索引的建立需要进行仔细分析:尽量考虑用单字段索引代替: A.正确选择复合索引中的主列字段,一般是选择性较好的字段: B.复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单

MySQL索引相关知识

MySQl索引创建 一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面的记录数量越多,这个操作的代价就越高.如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置.如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍. 假设我们创建了一个名为people的表: CREATE TABLE

MySQL 索引知识整理(创建高性能的索引)

前言: 索引优化应该是对查询性能优化的最有效的手段了.索引能够轻易将查询性能提高几个数量级. // 固态硬盘驱动器有和机械硬盘启动器,有着完全不同的性能特性: 然而即使是固态硬盘,索引的原则依然成立, 只是那些需要尽量避免的糟糕索引对固态硬盘的影响没有机械硬盘那么糟糕. 现在很多公司都将数据库的优化工作都依托于 DBA 去完成,在我看来,这些都应该是程序员必备的技能, 有经验和没经验的程序员在数据库使用起来也有很大的差异,这些差异取决开发人员对索引内部的数据结构认识, 对所有负责的业务熟悉程度,

MySQL索引的查看创建和删除

1.索引作用 在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍. 例如,有3个未索引的表t1.t2.t3,分别只包含列c1.c2.c3,每个表分别含有1000行数据组成,指为1-1000的数值,查找对应值相等行的查询如下所示. SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3 此查询结果应该为1000行,每行包含3个相

数据库优化(二)—— MySQL索引优化

目录 MySQL的索引优化 一.MySQL 5.7的初始化配置 二.MySQL配置文件 1.配置 2.配置文件作用 三.多实例 1.创建相关的目录 2.创建实例的配置文件 3.初始化 4.授权 5.启动实例 6.查看启动状况 7.测试 8.配置启动脚本 9.开机自启 10.设定mysql密码 11.忘记密码 四.数据类型 1.整型 2.字符串类型 3.时间类型 规范 五.索引 1.索引作用 2.索引种类 3.Btree 分类 4.聚集索引和辅助索引的对比 六.MySQL索引管理 1.创建索引(辅