`
被触发
  • 浏览: 37086 次
文章分类
社区版块
存档分类
最新评论

MySQL索引和优化查询

 
阅读更多
索引和优化查询
恰当的索引可以加快查询速度,可以分为四种类型:主键、唯一索引、全文索引、普通索引。
主键:唯一且没有null值。
create table pk_test(f1 int not null,primary key(f1));
alter table customer modify id int not null, add primary key(id);
普通索引:允许重复的值出现。
create table tableanme (fieldname1 columntype,fieldname2 columntype,index [indexname] (fieldname1 [,fieldname2...]));
create table tablename add index [indexname] (fieldname1 [fieldname2...]);
alter table slaes add index(value);
全文索引:用来对大表的文本域(char,varchar,text)进行索引。
语法和普通索引一样-fulltext。
使用全文索引:create table ft2 (f1 varchar(255),fulltext(f1));
insert into ft2 values(‘wating for the bvarbariands‘),(‘in the heart of the country‘),(‘the master of petersburg‘),(‘writing and being‘),(‘heart of the beast‘),(‘master master‘);
select * from ft2 where match(f1) against(‘master‘); // match()-匹配域;against()匹配值。
mysql会对某些字忽略,造成查询的误差:a. 50%以上的域出现的单词;b.少于三个字的单词;c.mysql预定义的列表,包括the。查询语句:select * from ft2 where match(f1) against(‘the master‘); // 与希望的结果是不同的
相关性分数查询:select f1,(match(f1) against(‘master‘)) from ft2;
mysql4的新功能-布尔全文查询:select * from ft2 where match(f1) against(‘+master -pet‘ in boolean mode); // 运算符类型 +-<>()~*"
唯一索引:除了不能有重复的记录外,其它和普通索引一样。
create table ui_test (f1 int,f2 int,unique(f1));
alter table ui_test add unique(f2);
对域(varchar,char,blob,text)的部分创建索引:alter table customer add index (surname(10));
自动增加域:每次插入记录时会自动增加一个域的值,只能用于一个域,且这个域有索引。
create table tablename(fieldname int auto_increment,[fieldname2...,] primary key(filedname));
alter table tablename modify fieldname columntype auto_increment;
last_insert_id()函数返回最新插入的自动增加值。
select last_insert_id() from customer limit 1;
此函数在多个连接同时进行时,会发生错误。
重置自动增加计数器的值:
create table tablename(fieldname int auto_increment,[fieldname2...,] primary key(filedname) auto_increment=50);
alter table tablename auto_increment=50;
如果重置的值比存在的值小,自动增加计数器会从记录中最大的那个值开始增加计数,比如customer表中的id已经有1、2、3、15、16、20,当把自动增加计数器的值设为1时,下次插入的记录会从21开始。
自动增加计数器的越界:有效值为1~2的127次方,即2147483647。如果超过这个值(包括负值),mysql会自动把它设为最大值,这样就会产生一个重复键值的错误。
自动增加域在多列索引中的使用:
create table staff(rank enum(‘employee‘,‘manager‘,‘contractor‘) not null,position varchar(100),id int not null auto_increment,primary key(rank,id));
insert into staff(rank,position) values(‘employee‘,‘cleaner‘),(‘cotractor‘,‘network maintenance‘),(‘manager‘,‘sales manager‘);
在对每个级别添加一些数据,会看到熟悉的自动增加现象:
insert into staff(rank,position) values(‘employee‘,‘cleaner1‘),(‘employee‘,‘network maintenance1‘),(‘manager‘,‘sales manager1‘);
在这种情况下是不能重置自动增加计数器的。
删除或更改索引:对索引的更改都需要先删除再重新定义。
alter table tablename drop primary key;
alter table table drop index indexname;
drop index on tablename;
高效使用索引:下面讨论的是用了索引会给我们带来什么?
1.) 获得域where从句中匹配的行:select * from customer where surname>‘c‘;
2.) 查找max()和min()值时,mysql只需在排序的索引中查找第一个和最后一个值。
3.) 返回的部分是索引的一部分,mysql就不需要去查询全表的数据而只需看索引:select id from customer;
4.) 对域使用order by的地方:select * from customer order by surname;
5.) 还可以加速表的连接:select first_name,surname,commission from sales,sales_rep where sales.sales_rep=sales_rep.employee_number and code=8;
6.) 在通配符的情况下:select * from sales_rep where surname like ‘ser%‘;
这种情况就不能起作用:select * from sales_rep where surname like ‘%ser%‘;
选择索引:
1.) 有查询需要使用索引(比如where从句中条件的域)的时候,要创建索引;不要不使用的域(不如第一个字符是通配符的)创建索引。
2.) 创建的索引返回的行越少越好,主键最好,枚举类型的索引不什么用处。
3.) 使用短索引(比如,名字的头十个字符而不是全部)。
4.) 不要创建太多的索引,虽然加快了查询的速度,但增加了更新的添加记录的时间。如果索引在查询中很少使用,而没有索引只是轻微的影响速度,就不要创建索引。
最左边规则:这种情况发生在多个有索引的域上,mysql从索引列表的最左边开始,按顺序使用他们。
alter table customer add initial varchar(5);
alter table customer add index(surname,initial,first_name);
update customer set initial=‘x‘ where id=1;
update customer set initial=‘c‘ where id=2;
update customer set initial=‘v‘ where id=3;
update customer set initial=‘b‘ where id=4;
update customer set initial=‘n‘ where id=20;
update customer set initial=‘m‘ where id=21;
如果在查询中使用了这三个域,那就最大限度的利用了索引:select * from customer where surname=‘clegg‘ and initial=‘x‘ and first_name=‘yvonne‘;
或者是利用索引的大部分:select * from customer where surname=‘clegg‘ and initial=‘x‘;
或仅仅是surname:select * from customer where surname=‘clegg‘;
如果打破最左边规则,下面的例子就不会用到索引:select * from customer where initial=‘x‘ and first_name=‘yvonne‘;
select * from customer where initial=‘x‘ ;
select * from customer where first_name=‘yvonne‘;
select * from customer where surname=‘clegg‘ and first_name=‘yvonne‘;

使用explain-解释mysql如何使用索引来处理select语句及连接表的。
输入 explain select * from customer; 后,出现一张表,个行的意思如下:
table-显示此行数据属于哪张表;type-重要的一列,显示使用了何种连接,从好到差依次为const、eq_ref、ref、range、index、all,下面会详细说明;possible_keys-可以应用在这张表中的索引,如果为null,则表示没有可用索引;key-实际使用的索引,如为null,表示没有用到索引;key_len-索引的长度,在不损失精确度的情况下,越短越好;ref-显示索引的哪一列被使用了,如果可能的话,是个常数;rows-返回请求数据的行数;extra-关于mysql如何解析查询的额外信息,下面会详细说明。
extra行的描述:distinct-mysql找到了域行联合匹配的行,就不再搜索了;
not exists-mysql优化了left join,一旦找到了匹配left join的行,就不再搜索了;
range checked for each-没找到理想的索引,一次对于从前面表中来的每一个行组合;
record(index map: #)-检查使用哪个索引,并用它从表中返回行,这是使用索引最慢的一种;
using filesort-看到这个就需要优化查询了,mysql需要额外的步骤来发现如何对返回的行排序。他根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。
using index-列数据是从单单使用了索引中的信息而没有读取实际行的表返回的,这发生在对表的全部的请求列都是同一个索引时;
using temporary-看到这个就需要优化查询了,mysql需要创建一个临时表来查询存储结果,这通常发生在多不同的列表进行order by时,而不是group by;
where used-使用了where从句来限制哪些行将与下一张表匹配或是返回给用户。如不想返回表中用的全部行,并连接类型是all或index,这就会发生,也可能是查询有问题。
type的描述:system-表只有一行,这是const连接类型的特例;const-表中一个记录的最大值能够匹配这个查询(索引可以是主键或唯一索引)。因为只有一行,这个值实际就是常数,因为mysql先读这个值,再把它当作常数对待;eq_ref-从前面的表中,对每一个记录的联合都从表中读取一个记录。在查询使用索引为主键或唯一索引的全部时使用;ref-只有使用了不是主键或唯一索引的部分时发生。对于前面表的每一行联合,全部记录都将从表中读出,这个连接类型严重依赖索引匹配记录的多少-越少越好;range-使用索引返回一个范围中的行,比如使用>或<查找时发生;index-这个连接类型对前面的表中的每一个记录联合进行完全扫描(比all好,因为索引一般小于表数据);all-这个连接类型多前面的表中的每一个记录联合进行完全扫描,这个比较糟糕,应该尽量避免。
举个例子:create index sales_rep on sales(sales_rep); // 可以比较一下创建索引前后的变化
explain select * from sales_rep left join sales on sales.sales_rep = sales_rep.employee_number;
结果如下:
table type possible_keys key key_len ref rows extra
sales_rep all null null null null 5
sales ref sales_rep sales_rep 5 sales_rep.employee_number 2
这个结果表示sales_rep表有个不好的连接类型-all,没用到索引,要查询的行数为5;sales的连接类型为ref,可用的索引是sales_rep,实际也使用sales_rep索引,这个索引的长度是5,对应的列是employee_number,要查询的行数为2,所以这次查询对表共进行了5×2次查询。

查看索引信息:show index from tablename;
列的描述:table-正在查看的表名;non_unique-1或1.0表示索引不能包含重复值(主键和唯一索引),1表示可以;key_name-索引名;seq_in_index-索引中列的顺序,从1开始;column_name-列名;collation-a或null,a表示索引以序升排列,null表示不排序;cardinality-索引中唯一值的个数;sub_part-如果整个列为索引,值为null,否则以字符表示索引的大小;packed-是否打包;null-如果列能包含null,则为yes;comment-各种注释。
分享到:
评论

相关推荐

    MySQL索引原理及慢查询优化1

    MySQL索引原理及慢查询优化是数据库管理中的重要主题,尤其是在高并发、大数据量的互联网环境中,优化查询性能对于系统的整体效能至关重要。MySQL作为广泛使用的开源关系型数据库,其索引机制和查询优化技巧是开发者...

    04-VIP-Mysql索引优化实战一.pdf

    总之,MySQL索引优化涉及到对查询语句的理解、索引设计的合理性以及根据数据量和查询模式选择合适的索引使用策略。在实际应用中,应结合`EXPLAIN`分析、性能测试和业务需求来调整索引和查询方式,以达到最佳的数据库...

    MySQL查询优化技术_索引.pdf

    MySQL查询优化技术_索引

    mysql的索引优化

    2. **索引优化**:合理选择索引类型和设计索引方案对于提高查询效率至关重要。例如,在经常被用作查询条件的列上创建索引可以显著提高查询速度。 3. **索引维护**:定期检查并优化索引结构也是必要的,以确保索引...

    MySQL索引优化课件

    MySQL索引优化是数据库性能提升的关键技术之一,尤其在处理大量数据时,高效索引能够显著加快查询速度,降低服务器负载。本课件主要聚焦于MySQL数据库的索引原理、优化策略以及相关存储过程和触发器的应用。 首先,...

    05-VIP-Mysql索引优化实战二.pdf

    本文档主要介绍了Mysql索引优化的实战经验,着重于分页查询优化和Join关联查询优化。 一、分页查询优化 在实际业务系统中,分页功能是非常常见的,对于大表的分页查询,执行效率往往非常低。例如,使用以下SQL语句...

    MySQL索引分析和优化.pdf

    ### MySQL索引分析和优化 #### 一、索引的重要性及原理 索引在数据库管理中扮演着极其重要的角色,特别是在提高数据检索速度方面。**MySQL索引**本质上是用来加快数据检索过程的一种数据结构,类似于书籍中的目录...

    尚硅谷mysql高级:索引、优化

    2. 索引优化:合理设计索引,根据查询模式创建最合适的索引。避免索引过多,因为这会增加写操作的开销。 3. 数据库设计:遵循第三范式,减少数据冗余,提高数据一致性。考虑数据分布,合理分区和分表。 4. 存储...

    MySQL索引:优化查询的利器.md

    MySQL索引:优化查询的利器

    mysql索引优化分享

    关于mysql索引一些优化介绍与创建原则,还有对order by排序的算法的介绍等等

    MySQL索引分析及优化.pdf

    "MySQL索引分析及优化" 索引是数据库中提高速度的一个关键因素。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。索引的使用可以大幅度地提高查询速度,减少数据库的...

    mysql查询优化之索引优化

    总之,索引优化是提升MySQL查询性能的核心手段,需要结合业务需求和查询模式,进行细致的分析和调整。通过以上策略的实施,可以显著减少查询时间,提升数据库系统的整体效率。在实际工作中,不断学习和实践,掌握...

    Mysql索引优化案例.pdf

    Mysql索引优化案例 在对数据库进行操作时,尤其是在处理包含大量数据的表时,查询的性能问题是一个常见且重要的话题。在实际工作中,对于Mysql数据库进行索引优化是提高查询效率、减少查询时间的重要手段。本案例将...

    Mysql的索引及优化策略

    Mysql的索引及优化策略,个人感觉还不错

    MySQL索引分析和优化[定义].pdf

    8. **索引优化**:MySQL提供了`EXPLAIN`关键字,可以帮助分析查询执行计划,了解是否正确使用了索引。通过`EXPLAIN`,可以发现查询是否进行了全表扫描、是否使用了索引、索引的类型以及索引的覆盖程度等信息,从而...

    MYSQL索引和优化详细说明教程

    MySQL索引和优化是数据库管理中的关键环节,它直接影响到数据查询的速度和效率。本教程将详细介绍MySQL中的索引类型及其优化策略。 首先,我们需要理解什么是索引。索引是数据库为了快速查找特定记录而创建的一种...

    MySQL索引 聚集索引

    MySQL索引 聚集索引 如果你想了解MySQL索引查询优化,你首先应该对MySQL数据组织结构、B-Tree索引、聚集索引,次要索引有一定的了解,才能够更好地理解MySQL查询优化行为。这里主要探讨MySQL InnoDB的聚集索引。

    MySQL索引与优化:原理、策略及高级应用

    内容概要:本文详细介绍了MySQL中索引的基本概念、创建和管理索引的策略、查询优化技术以及性能调优实践。...通过学习本文,读者可以掌握MySQL索引和优化的核心技术,从而提升数据库管理和开发能力。

    mysql索引优化方案技术分享

    mysql索引的优化方案技术分享,珍贵资料收藏下

Global site tag (gtag.js) - Google Analytics