通过实例认识MySQL中前缀索引的用法_Mysql

今天在测试环境中加一个索引时候发现一警告

root@test 07:57:52>alter table article drop index ind_article_url;
Query OK, 144384 rows affected (16.29 sec)
Records: 144384 Duplicates: 0 Warnings: 0
root@test 07:58:40>alter table article add index ind_article_url(url);
Query OK, 144384 rows affected, 1 warning (19.52 sec)
Records: 144384 Duplicates: 0 Warnings: 0
root@test 07:59:23>show warnings;
+———+——+———————————————————+
| Level  | Code | Message                         |
+———+——+———————————————————+
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
+———+——+———————————————————+
1 row in set (0.00 sec)

用show create table article查看索引以及表结构的信息:

`URL` varchar(512) default NULL COMMENT ‘外链url',
……
KEY `ind_article_url` (`URL`(383))
…..
DEFAULT CHARSET=gbk
……
drop table test;
create table test(test varchar(767) primary key)charset=latin5;

– 成功
接下来未测试,在不同的字符集:

drop table test;
create table test(test varchar(768) primary key)charset=latin5;

– 错误

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
drop table test;
create table test(test varchar(383) primary key)charset=GBK;

– 成功

drop table test;
create table test(test varchar(384) primary key)charset=GBK;

– 错误

 ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
drop table test;
create table test(test varchar(255) primary key)charset=UTF8;

– 成功

drop table test;
create table test(test varchar(256) primary key)charset=UTF8;

– 错误

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

MySQL的varchar索引只支持不超过768个字节 或者 768/2=384个双字节 或者 768/3=256个三字节的字段
而 GBK是双字节的,UTF-8是三字节的。
那么上面出现的原因就明了,我的字符集是为GBK为双字节,而url为512个字符,1024个字节,所以超过字符串索引的限制,报出了警告,mysql默认创建了383(766字节)长度的前缀索引。
我们知道小的索引大小不仅对空间存储,内存的降低和性能的提升有重大作用,那么在计算前缀索引的长度的时候,需要我们做出明智的选择,怎么明智?
全索引列的选择性:

root@test 08:10:35>select count(distinct(url))/count(*) from article;
+——————————-+
| count(distinct(url))/count(*) |
+——————————-+
|            0.0750 |
+——————————-+

对各种长度的前缀列计算其选择性:

root@test 08:16:41>select count(distinct left(url,76))/count(*) url_76,
-> count(distinct left(url,77))/count(*) url_77,
-> count(distinct left(url,78))/count(*) url_78,
-> count(distinct left(url,79))/count(*) url_79,
-> count(distinct left(url,80))/count(*) url_80,
-> count(distinct left(url,81))/count(*) url_81,
-> count(distinct left(url,82))/count(*) url_82,
-> count(distinct left(url,83))/count(*) url_83,
-> count(distinct left(url,84))/count(*) url_84,
-> count(distinct left(url,85))/count(*) url_85
-> from article;
+——–+——–+——–+——–+——–+——–+——–+——–+——–+——–+
| url_76 | url_77 | url_78 | url_79 | url_80 | url_81 | url_82 | url_83 | url_84 | url_85 |
+——–+——–+——–+——–+——–+——–+——–+——–+——–+——–+
| 0.0747 | 0.0748 | 0.0749 | 0.0749 | 0.0749 | 0.0749 | 0.0749 | 0.0749 | 0.0749 | 0.0750 |
+——–+——–+——–+——–+——–+——–+——–+——–+——–+——–+
1 row in set (1.82 sec)

我们看到选择85的长度的时候,该前缀列的选择性和全列的选择性相当了:
alter table article add index ind_article_url(url(85)),而不必选择383个字节作为前缀;
但是前缀索引还是有一点不足的地方,就是在查询语句中order by 和group by不能使用到前缀索引

root@test 08:49:24>explain select id,url,deleted from article group by url;
+—-+————-+————-+——+—————+——+———+——+——–+———————————+
| id | select_type | table    | type | possible_keys | key | key_len | ref | rows  | Extra              |
+—-+————-+————-+——+—————+——+———+——+——–+———————————+
| 1 | SIMPLE   | article | ALL | NULL     | NULL | NULL  | NULL | 139844 | Using temporary; Using filesort |
+—-+————-+————-+——+—————+——+———+——+——–+———————————+
1 row in set (0.00 sec);

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索mysql
mysql 前缀索引、mysql 前缀索引 语法、mysql 创建前缀索引、mysql 索引 最左前缀、mysql 索引 前缀长度,以便于您获取更多的相关知识。

时间: 2024-11-10 00:46:46

通过实例认识MySQL中前缀索引的用法_Mysql的相关文章

详细解读MySQL中COUNT函数的用法_Mysql

MySQL的COUNT函数是最简单的功能,非常有用的计算,预计由一个SELECT语句返回的记录数. 要了解COUNT函数考虑的EMPLOYEE_TBL的的表具有以下记录: mysql> SELECT * FROM employee_tbl; +------+------+------------+--------------------+ | id | name | work_date | daily_typing_pages | +------+------+------------+----

详解MySQL中WHERE子句的用法_Mysql

我们已经看到SQL SELECT命令来从MySQL表获取数据.我们可以使用一个条件子句WHERE子句中筛选出来的结果.使用WHERE子句,我们可以指定一个选择的标准来从表中选择所需的记录.语法: 下面是通用的SQL WHERE子句来获取数据从MySQL表的SELECT命令的语法: SELECT field1, field2,...fieldN table_name1, table_name2... [WHERE condition1 [AND [OR]] condition2.....    

mysql中字符串索引问题与例子

  字符串索引与数字索引有一些方面如果没做好会非常的慢了,今天我们就一起来看看小编整理的一些mysql中字符串索引问题与例子了,因为字符索引相对来说也简单文章就简单的整理了一些例子,希望对各位有帮助. 事情的起因是线上日志发现的mysql慢查询.100万数据量的标准,联合查询全部走索引的情况下,尽然要600多毫秒.很不解,但是将索引列由varchar(50)型改为bigint型后,数据提升了30倍.究其原因就索引树上搜索时要进行大量的比较操作,而字符串的比较比整数的比较耗时的多. 所以建议一般情

MySQL中对于索引的基本增删查改操作总结_Mysql

创建索引 MySQL创建索引的语法如下: CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON table_name (index_col_name,...) 其中对应的语法变量信息如下: [UNIQUE|FULLTEXT|SPATIAL] 中括号中的这三个关键字表示创建的索引类型,它们分别表示唯一索引.全文索引.空间索引三种不同的索引类型.如果我们不指定任何关键字,则默认为普通索引. index_name

MySQL中的索引

MySQL中的索引 作者:Jason Lee @http://blog.csdn.net/jasonblog 日期:2010-06-04 声明:本文发表在csdn博客,如有转载,请注明出处   [引言] 如图书馆等存放大量数据的场合都需要设置索引以方便检索.当数据库中存储的记录逐渐海量化的时候,合理地采用索引能大大改善程序性能.   [使用索引] 首先,创建一个用于测试的表: CREATE TABLE`test`.`books` ( `id` INT NOT NULLAUTO_INCREMENT

mysql中数据库索引与优化

一.索引的概念索引就是加快检索表中数据的方法.数据库的索引类似于书籍的索引.在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息.在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库. 二.索引的特点 1.索引可以加快数据库的检索速度 2.索引降低了数据库插入.修改.删除等维护任务的速度 3.索引创建在表上,不能创建在视图上 4.索引既可以直接创建,也可以间接创建 5.可以在优化隐藏中,使用索引 6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引

实例解析MySQL中的存储过程及存储过程的调用方法_Mysql

mysql在5.1之后增加了存储过程的功能, 存储过程运行在mysql内部,语句都已经编译好了,速度比sql更快. 存储过程与mysql相当于shell和linux系统.如果你是程序员的话,那我告诉你存储过程实际上是一个方法,你只要调用这个方法,并且输入它设置好的参数就可以获取或者执行你想要的操作了. 看了如下存储过程实例,你会发现mysql存储过程和shell很像. 下面存储过程内容为:调用存储过程,并且传入用户名,密码参数.存储过程会将这她们存储到process_test表里面.看实例 一,

MySQL中利用索引对数据进行排序的基础教程_Mysql

MySQL中,有两种方式生成有序结果集:一是使用filesort,二是按索引顺序扫描.利用索引进行排序操作是非常快的,而且可以利用同一索引同时进行查找和排序操作.当索引的顺序与ORDER BY中的列顺序相同且所有的列是同一方向(全部升序或者全部降序)时,可以使用索引来排序.如果查询是连接多个表,仅当ORDER BY中的所有列都是第一个表的列时才会使用索引.其它情况都会使用filesort. MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度.

MySQL Order By索引优化方法_Mysql

尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了. 使用索引的MySQL Order By 下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: 复制代码 代码如下: SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; SELECT * FROM t1 WHERE key_part1=constant ORD