>  기사  >  데이터 베이스  >  mysql index 사용법과 주의사항에 대한 자세한 설명

mysql index 사용법과 주의사항에 대한 자세한 설명

黄舟
黄舟원래의
2017-03-25 13:39:431165검색

이번 글은 mysql 인덱스 사용법과 주의사항을 위주로 소개하고 있는데 편집자가 꽤 좋다고 생각해서 공유합니다. 모두에게 참고가 되십시오. 에디터를 따라가서 살펴보자.

1. 인덱스의 역할

일반 애플리케이션 시스템의 읽기-쓰기 비율은 약 10:1, 삽입 작업 및 일반 업데이트 작업은 성능 문제를 거의 일으키지 않으며 문제를 일으킬 가능성이 가장 높은 작업은 일부 복잡한 쿼리 작업이므로 쿼리 문 최적화는 다음과 같습니다. 분명히 최우선 순위입니다.

데이터의 양과 접속량이 적을 때는 mysql 접속 속도가 매우 빠르며, 인덱스 추가 여부가 접속에 미치는 영향은 거의 없습니다. 그러나 데이터 양과 액세스 양이 급격하게 증가하면 MySQL 속도가 느려지거나 심지어 다운될 수도 있습니다. 이 경우 SQL 최적화를 고려해야 합니다. 데이터베이스에 대한 정확하고 합리적인 인덱스를 생성하는 것은 MySQL 최적화의 중요한 수단입니다.

인덱스의 목적은 쿼리 효율성을 높이는 것이며 이는 사전과 비교할 수 있습니다. "mysql"이라는 단어를 찾으려면 반드시 m 문자를 찾은 다음 y를 찾아야 합니다. 아래에서 아래로 문자를 입력한 다음 나머지 sql을 찾습니다. 색인이 없으면 원하는 것을 찾기 위해 모든 단어를 살펴봐야 할 수도 있습니다. 사전 외에도 기차역의 열차 시간표, 도서 목록 등 생활 곳곳에서 색인의 예를 볼 수 있습니다. 얻고자 하는 데이터의 범위를 지속적으로 좁힘으로써 원하는 최종 결과를 필터링할 수 있으며, 동시에 무작위 이벤트를 순차적 이벤트로 전환할 수 있습니다. 즉, 항상 동일한 검색을 사용합니다. 데이터를 잠그는 방법.

인덱스를 생성할 때 SQL 쿼리에 어떤 열이 사용될지 고려한 다음 해당 열에 대해 하나 이상의 인덱스를 생성해야 합니다. 실제로 인덱스는 기본 키 또는 인덱스 필드를 보유하는 테이블이자 각 레코드를 실제 테이블을 가리키는 포인터이기도 합니다. 인덱스는 데이터베이스 사용자에게 표시되지 않으며 쿼리 속도를 높이는 데만 사용됩니다. 데이터베이스 검색 엔진은 색인을 사용하여 레코드를 빠르게 찾습니다.

INSERT 및 UPDATE 문은 인덱스가 있는 테이블에서 실행하는 데 더 많은 시간이 걸리지만 SELECT 문은 더 빠르게 실행됩니다. 삽입이나 업데이트가 수행되면 데이터베이스도 인덱스 값을 삽입하거나 업데이트해야 하기 때문입니다.

2. 인덱스 생성 및 삭제

인덱스 종류 :

  1. UNIQUE(인덱스만) ): 같은 값이 나올 수 없으며 NULL 값이 있을 수 있음

  2. INDEX(일반 인덱스): 같은 인덱스 내용이 나올 수 있음

  3. PROMARY KEY(기본 키 인덱스): 동일한 값은 허용되지 않습니다.

  4. 전체 텍스트 인덱스(full text index): 값에서 특정 단어를 대상으로 할 수 있습니다. , 효율성은 정말 좋습니다. 부럽지 않습니다

  5. 결합 인덱스: 기본적으로 여러 필드가 하나의 인덱스에 내장되어 있으며, 열 값의 조합은 고유해야 합니다

(1) ALTER TABLE 문을 이용하여 간단히

을 생성하고, 테이블 생성 후 추가합니다.

ALTER TABLE 表名 ADD 索引类型 (unique,primary key,fulltext,index)[索引名](字段名)
//普通索引
alter table table_name add index index_name (column_list) ;
//唯一索引
alter table table_name add unique (column_list) ;
//主键索引
alter table table_name add primary key (column_list) ;

ALTER TABLE은 일반 인덱스, UNIQUE 인덱스 및 PRIMARY KEY 인덱스의 3가지 인덱스 형식을 생성하는 데 사용할 수 있습니다. table_name은 인덱스에 추가할 테이블의 이름입니다. 여러 개의 열이 있습니다. 각 열 사이는 쉼표로 구분하세요. 인덱스 이름 index_name은 선택 사항입니다. 기본적으로 MySQL은 첫 번째 인덱스 열을 기반으로 이름을 할당합니다. 또한 ALTER TABLE을 사용하면 단일 문에서 여러 테이블을 변경할 수 있으므로 여러 인덱스를 동시에 생성할 수 있습니다.

(2) CREATE INDEX 문을 사용하여 테이블에 인덱스를 추가합니다.

CREATE INDEX를 사용하여 테이블에 일반 인덱스 또는 UNIQUE 인덱스를 추가할 수 있습니다. 테이블을 만들 때 인덱스를 만드는 데 사용됩니다.

CREATE INDEX index_name ON table_name(username(length));

CHAR, VARCHAR 유형인 경우 길이는 필드의 실제 길이보다 작을 수 있으며, BLOB 및 TEXT 유형인 경우 길이를 지정해야 합니다.

//create只能添加这两种索引;
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

table_name, index_name, column_list는 ALTER TABLE 문과 동일한 의미를 가지며, 인덱스 이름은 선택 사항이 아닙니다. 또한 CREATE INDEX 문을 사용하여 PRIMARY KEY 인덱스를 생성할 수 없습니다.

(3) 인덱스 삭제

인덱스 삭제는 ALTER TABLE 또는 DROP INDEX 문을 사용하여 수행할 수 있습니다. DROP INDEX는 ALTER TABLE 내부에서 문장으로 처리할 수 있으며, 그 형식은

drop index index_name on table_name ;

alter table table_name drop index index_name ;

alter table table_name drop primary key ;

와 같다. 그 중 처음 두 문장에서는 table_name에 있는 index_name 인덱스가 삭제된다. 마지막 문에서는 PRIMARY KEY 인덱스를 삭제하는 데만 사용됩니다. 테이블에는 PRIMARY KEY 인덱스가 하나만 있을 수 있으므로 인덱스 이름을 지정할 필요가 없습니다. PRIMARY KEY 인덱스가 생성되지 않았지만 테이블에 하나 이상의 UNIQUE 인덱스가 있는 경우 MySQL은 첫 번째 UNIQUE 인덱스를 삭제합니다.

테이블에서 열이 삭제되면 인덱스가 영향을 받습니다. 다중 열 인덱스의 경우 열 중 하나가 삭제되면 해당 열도 인덱스에서 삭제됩니다. 인덱스를 구성하는 모든 컬럼을 삭제하면 인덱스 전체가 삭제됩니다.

(4) 조합지수와 접두어지수

在这里要指出,组合索引和前缀索引是对建立索引技巧的一种称呼,并不是索引的类型。为了更好的表述清楚,建立一个demo表如下。

create table USER_DEMO
(
  ID          int not null auto_increment comment '主键',
  LOGIN_NAME      varchar(100) not null comment '登录名',
  PASSWORD       varchar(100) not null comment '密码',
  CITY         varchar(30) not null comment '城市',
  AGE         int not null comment '年龄',
  SEX         int not null comment '性别(0:女 1:男)',
  primary key (ID)
);

为了进一步榨取mysql的效率,就可以考虑建立组合索引,即将LOGIN_NAME,CITY,AGE建到一个索引里:

代码如下:

ALTER TABLE USER_DEMO ADD INDEX name_city_age (LOGIN_NAME(16),CITY,AGE);

建表时,LOGIN_NAME长度为100,这里用16,是因为一般情况下名字的长度不会超过16,这样会加快索引查询速度,还会减少索引文件的大小,提高INSERT,UPDATE的更新速度。

如果分别给LOGIN_NAME,CITY,AGE建立单列索引,让该表有3个单列索引,查询时和组合索引的效率是大不一样的,甚至远远低于我们的组合索引。虽然此时有三个索引,但mysql只能用到其中的那个它认为似乎是最有效率的单列索引,另外两个是用不到的,也就是说还是一个全表扫描的过程。

建立这样的组合索引,就相当于分别建立如下三种组合索引:

LOGIN_NAME,CITY,AGE
LOGIN_NAME,CITY
LOGIN_NAME

为什么没有CITY,AGE等这样的组合索引呢?这是因为mysql组合索引“最左前缀”的结果。简单的理解就是只从最左边的开始组合,并不是只要包含这三列的查询都会用到该组合索引。也就是说name_city_age(LOGIN_NAME(16),CITY,AGE)从左到右进行索引,如果没有左前索引,mysql不会执行索引查询。

如果索引列长度过长,这种列索引时将会产生很大的索引文件,不便于操作,可以使用前缀索引方式进行索引,前缀索引应该控制在一个合适的点,控制在0.31黄金值即可(大于这个值就可以创建)。

SELECT COUNT(DISTINCT(LEFT(`title`,10)))/COUNT(*) FROM Arctic; -- 这个值大于0.31就可以创建前缀索引,Distinct去重复

ALTER TABLE `user` ADD INDEX `uname`(title(10)); -- 增加前缀索引SQL,将人名的索引建立在10,这样可以减少索引文件大小,加快索引查询速度

三.索引的使用及注意事项   

EXPLAIN可以帮助开发人员分析SQL问题,explain显示了mysql如何使用索引来处理select语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句。

使用方法,在select语句前加上Explain就可以了:

Explain select * from user where id=1;

尽量避免这些不走索引的sql:

SELECT `sname` FROM `stu` WHERE `age`+10=30;-- 不会使用索引,因为所有索引列参与了计算

SELECT `sname` FROM `stu` WHERE LEFT(`date`,4) <1990; -- 不会使用索引,因为使用了函数运算,原理与上面相同

SELECT * FROM `houdunwang` WHERE `uname` LIKE&#39;后盾%&#39; -- 走索引

SELECT * FROM `houdunwang` WHERE `uname` LIKE "%后盾%" -- 不走索引

-- 正则表达式不使用索引,这应该很好理解,所以为什么在SQL中很难看到regexp关键字的原因

-- 字符串与数字比较不使用索引;
CREATE TABLE `a` (`a` char(10));
EXPLAIN SELECT * FROM `a` WHERE `a`="1" -- 走索引
EXPLAIN SELECT * FROM `a` WHERE `a`=1 -- 不走索引

select * from dept where dname=&#39;xxx&#39; or loc=&#39;xx&#39; or deptno=45 
--如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字

-- 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

索引虽然好处很多,但过多的使用索引可能带来相反的问题,索引也是有缺点的:

  1. 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT,UPDATE和DELETE。因为更新表时,mysql不仅要保存数据,还要保存一下索引文件

  2. 建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在要给大表上建了多种组合索引,索引文件会膨胀很宽

索引只是提高效率的一个方式,如果mysql有大数据量的表,就要花时间研究建立最优的索引,或优化查询语句。

使用索引时,有一些技巧:

1.索引不会包含有NULL的列

只要列中包含有NULL值,都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此符合索引就是无效的。

 2.使用短索引

对串列进行索引,如果可以就应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

3.索引列排序

mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。

4.like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式。like ‘%aaa%'不会使用索引,而like ‘aaa%'可以使用索引。

5.不要在列上进行运算

6.不使用NOT IN 、a8093152e673feb7aba1828c43532094、!=操作,但211df07dbe7fea6e188a5b56353eb306,>=,BETWEEN,IN是可以用到索引的

7.索引要建立在经常进行select操作的字段上。

这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

8.索引要建立在值比较唯一的字段上。

9.对于那些定义为text、image和bit数据类型的列不应该增加索引。因为这些列的数据量要么相当大,要么取值很少。

10.在where和join中出现的列需要建立索引。

11. where의 쿼리 조건에 부등호(where 컬럼 != ...)가 있으면 mysql은 인덱스를 사용할 수 없습니다.

12. where 절의 쿼리 조건에 함수가 사용되면(예: where DAY (column) =...) mysql은 인덱스를 사용할 수 없습니다.

13. 조인 작업(여러 데이터 테이블에서 데이터를 추출해야 하는 경우)에서 mysql은 기본 키와 외래 키의 데이터 유형이 동일한 경우에만 인덱스를 사용할 수 있으며, 그렇지 않으면 인덱스를 사용할 수 있습니다. 시간 내에 확립되면 사용되지 않습니다.

위 내용은 mysql index 사용법과 주의사항에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.