数据库——索引的本质,分类及使用

数据库——索引

索引的本质

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构

索引在小数据时用处不大,但在大数据时用处十分明显

索引的分类

  • 主键索引(PRIMARY KEY)
    • 唯一的标识,主键不可重复,只能有一个列作为主键
  • 唯一索引(UNIQUE KEY)
    • 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
  • 常规索引(KEY/INDEX)
    • 默认的,不写就有。也可以用index或者key关键字来设置
  • 全文索引(FullText)
    • 在特定的数据引擎下才有,如MYISAM
    • 快速定位数据

索引的使用

创建索引的方式


-- 增加一个索引   格式1:     索引类型         索引名     要加索引的列名
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)

-- 增加一个索引 格式二    
-- CREATE INDEX(常规索引)/FULLTEXT(全文索引) 索引名 on 表(字段)  id_表名字_字段名为索引名
CREATE INDEX id_app_user_name ON`app_user`(`name`) -- 创建索引可以大大增加查询速度

-- 方式三  在建表的时候加索引
CREATE TABLE test1 (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    content TEXT NOT NULL,
    PRIMARY KEY(id),  -- 建了主键索引
    FULLTEXT KEY content_index(content)-- 创建了全文索引
) ENGINE=MYISAM DEFAULT CHARSET=utf8;

删除索引的方式

-- 方式一
DROP INDEX 索引名 ON 表名

-- 方式二
ALTER TABLE 表名 DROP INDEX 索引名
-- 分析SQL执行的状况
EXPLAIN SELECT * FROM student 

索引原则

  • 索引不是越多越好
  • 不要对经常变动的数据加索引
  • 小数据量的表不需要加索引
  • 索引一般用在经常查询到字段上

索引测试

-- =========================索引==========================
-- 索引的使用
-- 1. 在创建表的时候给字段增加索引
-- 2. 创建完毕后,增加索引
-- 3. 通过ALTER TABLE创建或删除全文索引
-- 4. 直接使用DROP INDEX删除全文索引


-- 显示所有的索引信息
SHOW INDEX FROM student

-- 增加一个索引   格式1:     索引类型         索引名     要加索引的列名
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)


-- 分析SQL执行的状况
EXPLAIN SELECT * FROM student  -- 非全文索引

EXPLAIN SELECT * FROM student WHERE MATCH(`studentname`) AGAINST('张三')-- 全文索引
/*使用 match 和 against 关键字
 注意: match() 函数中指定的列必须和全文索引中指定的列完全相同,否则就会报错,
无法使用全文索引,这是因为全文索引不会记录关键字来自哪一列。
如果想要对某一列使用全文索引,请单独为该列创建全文索引。
*/

SELECT  VERSION()

-- 全文索引测试
CREATE TABLE test1 (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    content TEXT NOT NULL,
    PRIMARY KEY(id),
    FULLTEXT KEY content_index(content)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;

INSERT INTO test1 (content) VALUES ('a'),('b'),('c');
INSERT INTO test1 (content) VALUES ('aa'),('bb'),('cc');
INSERT INTO test1(content) VALUES ('aaa'),('bbb'),('ccc');
INSERT INTO test1 (content) VALUES ('aaaa'),('bbbb'),('cccc');


SELECT * FROM test1 WHERE MATCH(content) AGAINST('a');
SELECT * FROM test1 WHERE MATCH(content) AGAINST('aa');
SELECT * FROM test1 WHERE MATCH(content) AGAINST('aaa');
SELECT * FROM test1 WHERE MATCH(content) AGAINST('aaaa');

SHOW VARIABLES LIKE '%ft%';

-- =====================索引测试========================
CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT '',
`email` VARCHAR(50) NOT NULL,
`phone` VARCHAR(20) DEFAULT '',
`gender` TINYINT(4) UNSIGNED DEFAULT '0',
`password` VARCHAR(100) NOT NULL DEFAULT '',
`age` TINYINT(4) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


-- 百万数据插入
DROP FUNCTION IF EXISTS mock_data;
-- 写函数之前必须要写标志:$$
DELIMITER $$
CREATE FUNCTION mock_data()-- 创建一个函数
RETURNS INT -- 返回一个值
-- 注意returns,否则报错。
BEGIN     -- 函数体
DECLARE num INT DEFAULT 1000000;-- num 作为截止数字,定义为百万,
DECLARE i INT DEFAULT 0; -- 定义起始变量
WHILE i < num DO
   -- 插入语句
   INSERT INTO app_user(`name`, `email`, `phone`, `gender`, `password`, `age`)
   VALUES(CONCAT('用户', i), CONCAT('100',i,'[email protected]'), CONCAT('18', FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(), FLOOR(RAND()*100));
   SET i = i + 1;
END WHILE; -- 循环结束
RETURN i;
END;
SELECT  mock_data();-- 开始执行


SELECT * FROM `app_user` WHERE `name`='用户1988'

-- 分析SQL执行的状况  
EXPLAIN SELECT * FROM `app_user` WHERE `name`='用户1988'-- 显示共查询了991770行数据才查询到'用户1988'的信息

-- 增加一个索引 格式二    
-- CREATE INDEX(常规索引)/FULLTEXT(全文索引) 索引名 on 表(字段)  id_表名字_字段名为索引名
CREATE INDEX id_app_user_name ON`app_user`(`name`) -- 创建索引可以大大增加查询速度

-- 分析SQL执行的状况  
EXPLAIN SELECT * FROM `app_user` WHERE `name`='用户1988'--  增加索引后,显示只查询了1行数据就查询到'用户1988'的信息

猜你喜欢

转载自blog.csdn.net/wpc2018/article/details/109008209
今日推荐