mysql索引创建和使用细节
Posted 星辰大海才是终点
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql索引创建和使用细节相关的知识,希望对你有一定的参考价值。
上篇粗略记录当mysql字段类型是string,传入int类型参数后失效当问题。
现在测试下mysql字段是int类型,传参string类型会发生什么。
题外话,最近膝盖手术后还在家养伤中,只怪自己以前骑车不注意休息保养,经常长途骑行出去玩,把膝盖骑费了(抽取积液+切除膝盖囊肿手术),搞得现在哪都去不了,已经一周没下楼走走。
【索引失效】
二. 单字段索引:字段是INT类型,传入string类型参数
MySQL [test_db]> show create table test_usersG; *************************** 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_logG; *************************** 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)
以上是关于mysql索引创建和使用细节的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段