欢迎来到千学网!
您现在的位置:首页 > 实用文 > 其他范文

加速动态网站之MySQL索引分析和优化数据库

时间:2023-07-31 09:06:34 其他范文 收藏本文 下载本文

这里小编给大家分享一些加速动态网站之MySQL索引分析和优化数据库,本文共9篇,方便大家学习。

加速动态网站之MySQL索引分析和优化数据库

篇1:加速动态网站之MySQL索引分析和优化数据库

一、什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有 MySQL 索引都以B-树的形式保存,如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。 如果作

一、什么是索引?

索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。

假设我们创建了一个名为people的表:

CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );

然后,我们完全随机把1000个不同name值插入到people表。下图显示了people表所在数据文件的一小部分:

可以看到,在数据文件中name列没有任何明确的次序。如果我们创建了name列的索引,MySQL将在索引中排序name列:

对于索引中的每一项,MySQL在内部为它保存一个数据文件中实际记录所在位置的“指针”。因此,如果我们要查找name等于“Mike”记录的peopleid(SQL命令为“SELECT peopleid FROM people WHERE name='Mike';”),MySQL能够在name的索引中查找“Mike”值,然后直接转到数据文件中相应的行,准确地返回该行的peopleid(999)。在这个过程中,MySQL只需处理一个行就可以返回结果。如果没有“name”列的索引,MySQL要扫描数据文件中的所有记录,即1000个记录!显然,需要MySQL处理的记录数量越少,则它完成任务的速度就越快。

二、索引的类型

MySQL提供多种索引类型供选择:

普通索引

这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:

创建索引,例如CREATE INDEX<索引的名字>ON tablename (列的列表);

修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);

创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );

唯一性索引

这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。唯一性索引可以用以下几种方式创建:

创建索引,例如CREATE UNIQUE INDEX<索引的名字>ON tablename (列的列表);

修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);

创建表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );

主键

主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。

全文索引

MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引,要了解更多信息,请参见MySQL documentation。

三、单列索引与多列索引

索引可以是单列索引,也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表:

CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50) NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT NULL, PRIMARY KEY (peopleid) );

下面是我们插入到这个people表的数据:

这个数据片段中有四个名字为“Mikes”的人(其中两个姓Sullivans,两个姓McConnells),有两个年龄为17岁的人,还有一个名字与众不同的Joe Smith。

这个表的主要用途是根据指定的用户姓、名以及年龄返回相应的peopleid。例如,我们可能需要查找姓名为Mike Sullivan、年龄17岁用户的peopleid(SQL命令为SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。由于我们不想让MySQL每次执行查询就去扫描整个表,这里需要考虑运用索引。

首先,我们可以考虑在单个列上创建索引,比如firstname、lastname或者age列,

如果我们创建firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL将通过这个索引迅速把搜索范围限制到那些firstname='Mike'的记录,然后再在这个“中间结果集”上进行其他条件的搜索:它首先排除那些lastname不等于“Sullivan”的记录,然后排除那些age不等于17的记录。当记录满足所有搜索条件之后,MySQL就返回最终的搜索结果。

由于建立了firstname列的索引,与执行表的完全扫描相比,MySQL的效率提高了很多,但我们要求MySQL扫描的记录数量仍旧远远超过了实际所需要的。虽然我们可以删除firstname列上的索引,再创建lastname或者age列的索引,但总地看来,不论在哪个列上创建索引搜索效率仍旧相似。

为了提高搜索效率,我们需要考虑运用多列索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个多列索引的SQL命令:

ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、age的多列索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

四、最左前缀

多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。继续考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列索引,我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引:

firstname,lastname,age

firstname,lastname

firstname

从另一方面理解,它相当于我们创建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引:

SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; SELECT peopleid FROM people WHERE firstname='Mike'; The following queries cannot use the index at all: SELECT peopleid FROM people WHERE lastname='Sullivan'; SELECT peopleid FROM people WHERE age='17'; SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';

五、选择索引列

在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:在WHERE子句中出现的列,在join子句中出现的列。请看下面这个查询:

SELECT age ## 不使用索引

FROM people WHERE firstname='Mike' ## 考虑使用索引

AND lastname='Sullivan' ## 考虑使用索引

这个查询与前面的查询略有不同,但仍属于简单查询。由于age是在SELECT部分被引用,MySQL不会用它来限制列选择操作。因此,对于这个查询来说,创建age列的索引没有什么必要。下面是一个更复杂的例子:

SELECT people.age, ##不使用索引

town.name ##不使用索引

FROM people LEFT JOIN town ON

people.townid=town.townid ##考虑使用索引

WHERE firstname='Mike' ##考虑使用索引

AND lastname='Sullivan' ##考虑使用索引

与前面的例子一样,由于firstname和lastname出现在WHERE子句中,因此这两个列仍旧有创建索引的必要。除此之外,由于town表的townid列出现在join子句中,因此我们需要考虑创建该列的索引。

那么,我们是否可以简单地认为应该索引WHERE子句和join子句中出现的每一个列呢?差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。例如,“SELECT peopleid FROM people WHERE firstname LIKE 'Mich%';”这个查询将使用索引,但“SELECT peopleid FROM people WHERE firstname LIKE '%ike';”这个查询不会使用索引。

六、分析索引效率

现在我们已经知道了一些如何选择索引列的知识,但还无法判断哪一个最有效。MySQL提供了一个内建的SQL命令帮助

原文转自:www.ltesting.net

篇2:mysql数据库动态创建表

mysql数据库动态创建表

大家一般可能很少有这种需求吧,我以前也没有遇到过,但这次做项目需要这么做,

就是表的字段名和字段数都不是固定的,要根据需要来创建。

这是我的创建形成过程,大家照着演示一下就知道了我的动态表的来龙去脉了。

第一步.创建相关表

/*---建立所有指标信息的临时表---*/

drop table if exists INTERBANKBONDQUOTE_SClass;

create table INTERBANKBONDQUOTE_SClass (

Name varchar(50) not null,

id int Primary key,

Parent int,

Value varchar(50)

);

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('最新成交',0,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('买入信息',1,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('买卖价差',2,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('卖出信息',3,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Parent,Value)values('中债最新估值',4,-1,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('含权债行权指标',5,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('基础指标',6,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Value)values('双边报价笔数',7,'');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Parent,Value)values('报价方',8,1,'col4');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Parent,Value)values('报价方会员号',9,1,'col5');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Parent,Value)values('报价时间',10,1,'col6');

insert into INTERBANKBONDQUOTE_SClass(Name,id,Parent,Value)values('匿名',11,1,'col7');

第二步:/*---建立显示数据表格标题的表---*/

drop table if exists INTERBANKBONDQUOTE_T;

create table INTERBANKBONDQUOTE_T as select concat('\'',a.Name,',',b.Name,'\' __TITLE__',b.Value);

第三步: 这里有两种实现方法。因为在mysql中,这时的变量长度受到了限制 ,本来应该longtext足够长的,可实际只返回了限制长度的。如果字段太多了,就要用第二种方法。

存储过程A: 这里变量返回值长度受限,字段不多时可以。

DELIMITER $$

DROP PROCEDURE IF EXISTS `dzhappdb_bond`.`INTERBANKBONDQUOTE_TSP`$$

CREATE PROCEDURE INTERBANKBONDQUOTE_TSP

BEGIN

DECLARE objs1 TEXT;

DECLARE objs TEXT;

SELECT GROUP_CONCAT(col1) INTO objs1 FROM T;

SET objs =CONCAT('CREATE TABLE Title AS SELECT ',objs1);

SET @sql_txt = objs;

PREPARE stmt FROM @sql_txt;

EXECUTE stmt;

DEALLOCATE PREPARE stmt;

END$$

call INTERBANKBONDQUOTE_TSP;

存储过程B:这样不管字段多少,只要数据库支持就可以创建成功,

但不如第一个方法简洁。

DROP PROCEDURE IF EXISTS INTERBANKBONDQUOTE_TSP_Title;

drop table if EXISTS Title;

CREATE PROCEDURE INTERBANKBONDQUOTE_TSP_Title()

proc:begin

DECLARE add_sql LONGTEXT;

DECLARE insert_sql LONGTEXT;

DECLARE nhh_sql varchar(200);

DECLARE column_name varchar(100);

DECLARE column_value varchar(100);

DECLARE mycount int;

DECLARE len int;

DECLARE strlen int;

DECLARE cursor_Title CURSOR for select col1 from INTERBANKBONDQUOTE_T;

create table Title(mid int);

insert into Title values (100);

select count(col1) into @mycount from INTERBANKBONDQUOTE_T;

OPEN cursor_Title;

REPEAT

FETCH cursor_Title INTO nhh_sql;

begin

set @mycount=@mycount-1;

set @strlen=CHARACTER_LENGTH(nhh_sql);

set @len=INSTR(nhh_sql,' ');

set @column_name=RIGHT(nhh_sql,@strlen-@len);

set @column_value=LEFT(nhh_sql,@len);

set @add_sql=CONCAT('ALTER table Title add COLUMN ',@column_name,' varchar(100)');

set @insert_sql=CONCAT('update Title set ',@column_name,'=',@column_value,' where mid=100');

PREPARE stmt1 FROM @add_sql;

EXECUTE stmt1;

PREPARE stmt2 FROM @insert_sql;

EXECUTE stmt2;

DEALLOCATE PREPARE stmt1;

DEALLOCATE PREPARE stmt2;

end;

until @mycount<=0

END REPEAT;

CLOSE cursor_Title;

ALTER table Title drop column mid;

end proc;

call INTERBANKBONDQUOTE_TSP_Title;

篇3:MySQL查询优化技术系列讲座之使用索引

索引是提高查询速度的最重要的工具,当然还有其它的一些技术可供使用,但是一般来说引起最大性能差异的都是索引的正确使用。在MySQL邮件列表中,人们经常询问那些让查询运行得更快的方法。在大多数情况下,我们应该怀疑数据表上有没有索引,并且通常在添加索引之后立即解决了问题。当然,并不总是这样简单就可以解决问题的,因为优化技术本来就并非总是简单的。然而,如果没有使用索引,在很多情况下,你试图使用其它的方法来提高性能都是在浪费时间。首先使用索引来获取最大的性能提高,接着再看其它的技术是否有用。

这一部分讲述了索引是什么以及索引是怎么样提高查询性能的。它还讨论了在某些环境中索引可能降低性能,并为你明智地选择数据表的索引提供了一些指导方针。在下一部分中我们将讨论MySQL查询优化器,它试图找到执行查询的效率最高的方法。了解一些优化器的知识,作为对如何建立索引的补充,对我们是有好处的,因为这样你才能更好地利用自己所建立的索引。某些编写查询的方法实际上让索引不起作用,在一般情况下你应该避免这种情形的发生。

索引的优点

让我们开始了解索引是如何工作的,首先有一个不带索引的数据表。不带索引的表仅仅是一个无序的数据行集合。例如,图1显示的ad表就是不带索引的表,因此如果需要查找某个特定的公司,就必须检查表中的每个数据行看它是否与目标值相匹配。这会导致一次完全的数据表扫描,这个过程会很慢,如果这个表很大,但是只包含少量的符合条件的记录,那么效率会非常低。

图1:无索引的ad表

图2是同样的一张数据表,但是增加了对ad表的company_num数据列的索引。这个索引包含了ad表中的每个数据行的条目,但是索引的条目是按照company_num值排序的。现在,我们不是逐行查看以搜寻匹配的数据项,而是使用索引。假设我们查找公司13的所有数据行。我们开始扫描索引并找到了该公司的三个值。接着我们碰到了公司14的索引值,它比我们正在搜寻的值大。索引值是排过序的,因此当我们读取了包含14的索引记录的时候,我们就知道再也不会有更多的匹配记录,可以结束查询操作了。因此使用索引获得的功效是:我们找到了匹配的数据行在哪儿终止,并能够忽略其它的数据行。另一个功效来自使用定位算法查找第一条匹配的条目,而不需要从索引头开始执行线性扫描(例如,二分搜索就比线性扫描要快一些)。通过使用这种方法,我们可以快速地定位第一个匹配的值,节省了大量的搜索时间。数据库使用了多种技术来快速地定位索引值,但是在本文中我们不关心这些技术。重点是它们能够实现,并且索引是个好东西。

图2:索引后的ad表

你可能要问,我们为什么不对数据行进行排序从而省掉索引?这样不是也能实现同样的搜索速度的改善吗?是的,如果表只有一个索引,这样做也可能达到相同的效果。但是你可能添加第二个索引,那么就无法一次使用两种不同方法对数据行进行排序了(例如,你可能希望在顾客名称上建立一个索引,在顾客ID号或电话号码上建立另外一个索引)。把与数据行相分离的条目作为索引解决了这个问题,允许我们创建多个索引。此外,索引中的行一般也比数据行短一些。当你插入或删除新的值的时候,移动较短的索引值比移动较长数据行的排序次序更加容易。

不同的MySQL存储引擎的索引实现的具体细节信息是不同的。例如,对于MyISAM数据表,该表的数据行保存在一个数据文件中,索引值保存在索引文件中。一个数据表上可能有多个索引,但是它们都被存储在同一个索引文件中。索引文件中的每个索引都包含一个排序的键记录(它用于快速地访问数据文件)数组。

与此形成对照的是,BDB和InnoDB存储引擎没有使用这种方法来分离数据行和索引值,尽管它们也把索引作为排序后的值集合进行操作。在默认情况下,BDB引擎使用单个文件存储数据和索引值。InnoDB使用单个数据表空间(tablespace),在表空间中管理所有InnoDB表的数据和索引存储。我们可以把InnoDB配置为每个表都在自己的表空间中创建,但是即使是这样,数据表的数据和索引也存储在同一个表空间文件中。

前面的讨论描述了单个表查询环境下的索引的优点,在这种情况下,通过减少对整个表的扫描,使用索引明显地提高了搜索的速度。当你运行涉及多表联结(jion)查询的时候,索引的价值就更高了。在单表查询中,你需要在每个数据列上检查的值的数量是表中数据行的数量。在多表查询中,这个数量可能大幅度上升,因为这个数量是这些表中数据行的数量所产生的。

假设你拥有三个未索引的表t1、t2和t3,每个表都分别包含数据列i1、i2和i3,并且每个表都包含了1000条数据行,其序号从1到1000。查找某些值匹配的数据行组合的查询可能如下所示:

SELECT t1.i1, t2.i2, t3.i3

FROM t1, t2, t3

WHERE t1.i1 = t2.i2 AND t2.i1 = t3.i3;

这个查询的结果应该是1000行,每个数据行包含三个相等的值。如果在没有索引的情况下处理这个查询,那么如果我们不对这些表进行全部地扫描,我们是没有办法知道哪些数据行含有哪些值的。因此你必须尝试所有的组合来查找符合WHERE条件的记录。可能的组合的数量是1000 x 1000 x 1000(10亿!),它是匹配记录的数量的一百万倍。这就浪费了大量的工作。这个例子显示,如果没有使用索引,随着表的记录不断增长,处理这些表的联结所花费的时间增长得更快,导致性能很差。我们可以通过索引这些数据表来显著地提高速度,因为索引让查询采用如下所示的方式来处理:

1.选择表t1中的第一行并查看该数据行的值。

2.使用表t2上的索引,直接定位到与t1的值匹配的数据行。类似地,使用表t3上的索引,直接定位到与表t2的值匹配的数据行。

3.处理表t1的下一行并重复前面的过程。执行这样的操作直到t1中的所有数据行都被检查过。

在这种情况下,我们仍然对表t1执行了完整的扫描,但是我们可以在t2和t3上执行索引查找,从这些表中直接地获取数据行。理论上采用这种方式运行上面的查询会快一百万倍。当然这个例子是为了得出结论来人为建立的。然而,它解决的问题却是现实的,给没有索引的表添加索引通常会获得惊人的性能提高。

MySQL有几种使用索引的方式:

· 如上所述,索引被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度。

· 对于使用了MIN()或MAX()函数的查询,索引数据列中最小或最大值可以很快地找到,不用检查每个数据行。

· MySQL利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作。

· 有时候MySQL会利用索引来读取查询得到的所有信息。假设你选择了MyISAM表中的被索引的数值列,那么就不需要从该数据表中选择其它的数据列。在这种情况下,MySQL从索引文件中读取索引值,它所得到的值与读取数据文件得到的值是相同的。没有必要两次读取相同的值,因此没有必要考虑数据文件。

索引的代价

一般来说,如果MySQL能够找到方法,利用索引来更快地处理查询,它就会这样做。这意味着,对于大多数情况,如果你没有对表进行索引,就会使性能受到损害。这就是我所描绘的索引优点的美景。但是它有缺点吗?有的,它在时间和空间上都有开销。在实践中,索引的优点的价值一般会超过这些缺点,但是你也应该知道到底有一些什么缺点。

首先,索引加快了检索的速度,但是减慢了插入和删除的速度,同时还减慢了更新被索引的数据列中的值的速度。也就是说,索引减慢了大多数涉及写操作的速度。发生这种现象的原因在于写入一条记录的时候不但需要写入数据行,还需要改变所有的索引。数据表带有的索引越多,需要做出的修改就越多,平均性能的降低程度也就越大。在本文的“高效率载入数据”部分中,我们将更细致地了解这些现象并找出处理方法。

其次,索引会花费磁盘空间,多个索引相应地花费更多的磁盘空间。这可能导致更快地到达数据表的大小限制:

· 对于MyISAM表,频繁地索引可能引起索引文件比数据文件更快地达到最大限制。

· 对于BDB表,它把数据和索引值一起存储在同一个文件中,添加索引引起这种表更快地达到最大文件限制。

在InnoDB的共享表空间中分配的所有表都竞争使用相同的公共空间池,因此添加索引会更快地耗尽表空间中的存储。但是,与MyISAM和BDB表使用的文件不同,InnoDB共享表空间并不受操作系统的文件大小限制,因为我们可以把它配置成使用多个文件。只要有额外的磁盘空间,你就可以通过添加新组件来扩展表空间。

使用单独表空间的InnoDB表与BDB表受到的约束是一样的,因为它的数据和索引值都存储在单个文件中,

这些要素的实际含义是:如果你不需要使用特殊的索引帮助查询执行得更快,就不要建立索引。

选择索引

假设你已经知道了建立索引的语法,但是语法不会告诉你数据表应该如何索引。这要求我们考虑数据表的使用方式。这一部分指导你如何识别出用于索引的备选数据列,以及如何最好地建立索引:

用于搜索、排序和分组的索引数据列并不仅仅是用于输出显示的。换句话说,用于索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是很好的备选列:

SELECT

col_a <- 不是备选列

FROM

tbl1 LEFT JOIN tbl2

ON tbl1.col_b = tbl2.col_c <- 备选列

WHERE

col_d = expr; <- 备选列

当然,显示的数据列与WHERE子句中使用的数据列也可能相同。我们的观点是输出列表中的数据列本质上不是用于索引的很好的备选列。

Join子句或WHERE子句中类似col1 = col2形式的表达式中的数据列都是特别好的索引备选列。前面显示的查询中的col_b和col_c就是这样的例子。如果MySQL能够利用联结列来优化查询,它一定会通过减少整表扫描来大幅度减少潜在的表-行组合。

考虑数据列的基数(cardinality)。基数是数据列所包含的不同值的数量。例如,某个数据列包含值1、3、7、4、7、3,那么它的基数就是4。索引的基数相对于数据表行数较高(也就是说,列中包含很多不同的值,重复的值很少)的时候,它的工作效果最好。如果某数据列含有很多不同的年龄,索引会很快地分辨数据行。如果某个数据列用于记录性别(只有“M”和“F”两种值),那么索引的用处就不大。如果值出现的几率几乎相等,那么无论搜索哪个值都可能得到一半的数据行。在这些情况下,最好根本不要使用索引,因为查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。惯用的百分比界线是“30%”。现在查询优化器更加复杂,把其它一些因素也考虑进去了,因此这个百分比并不是MySQL决定选择使用扫描还是索引的唯一因素。

索引较短的值。尽可能地使用较小的数据类型。例如,如果MEDIUMINT足够保存你需要存储的值,就不要使用BIGINT数据列。如果你的值不会长于25个字符,就不要使用CHAR(100)。较小的值通过几个方面改善了索引的处理速度:

· 较短的值可以更快地进行比较,因此索引的查找速度更快了。

· 较小的值导致较小的索引,需要更少的磁盘I/O。

· 使用较短的键值的时候,键缓存中的索引块(block)可以保存更多的键值。MySQL可以在内存中一次保持更多的键,在不需要从磁盘读取额外的索引块的情况下,提高键值定位的可能性。

对于InnoDB和BDB等使用聚簇索引(clustered index)的存储引擎来说,保持主键(primary key)短小的优势更突出。聚簇索引中数据行和主键值存储在一起(聚簇在一起)。其它的索引都是次级索引;它们存储主键值和次级索引值。次级索引屈从主键值,它们被用于定位数据行。这暗示主键值都被复制到每个次级索引中,因此如果主键值很长,每个次级索引就需要更多的额外空间。

索引字符串值的前缀(prefixe)。如果你需要索引一个字符串数据列,那么最好在任何适当的情况下都应该指定前缀长度。例如,如果有CHAR(200)数据列,如果前面10个或20个字符都不同,就不要索引整个数据列。索引前面10个或20个字符会节省大量的空间,并且可能使你的查询速度更快。通过索引较短的值,你可以获得那些与比较速度和磁盘I/O节省相关的好处。当然你也需要利用常识。仅仅索引某个数据列的第一个字符串可能用处不大,因为如果这样操作,那么在索引中不会有太多的唯一值。

你可以索引CHAR、VARCHAR、BINARY、VARBINARY、BLOB和TEXT数据列的前缀。

使用最左(leftmost)前缀。建立多列复合索引的时候,你实际上建立了MySQL可以使用的多个索引。复合索引可以作为多个索引使用,因为索引中最左边的列集合都可以用于匹配数据行。这种列集合被称为“最左前缀”(它与索引某个列的前缀不同,那种索引把某个列的前面几个字符作为索引值)。

假设你在表的state、city和zip数据列上建立了复合索引。索引中的数据行按照state/city/zip次序排列,因此它们也会自动地按照state/city和state次序排列。这意味着,即使你在查询中只指定了state值,或者指定state和city值,MySQL也可以使用这个索引。因此,这个索引可以被用于搜索如下所示的数据列组合:

state, city, zip

state, city

state

MySQL不能利用这个索引来搜索没有包含在最左前缀的内容。例如,如果你按照city或zip来搜索,就不会使用到这个索引。如果你搜索给定的state和具体的ZIP代码(索引的1和3列),该索引也是不能用于这种组合值的,尽管MySQL可以利用索引来查找匹配的state从而缩小搜索的范围。

不要过多地索引。不要认为“索引越多,性能越高”,不要对每个数据列都进行索引。我们在前面提到过,每个额外的索引都会花费更多的磁盘空间,并降低写操作的性能。当你修改表的内容的时候,索引就必须被更新,甚至可能重新整理。如果你的索引很少使用或永不使用,你就没有必要减小表的修改操作的速度。此外,为检索操作生成执行计划的时候,MySQL会考虑索引。建立额外的索引会给查询优化器增加更多的工作量。如果索引太多,有可能(未必)出现MySQL选择最优索引失败的情况。维护自己必须的索引可以帮助查询优化器来避免这类错误。

如果你考虑给已经索引过的表添加索引,那么就要考虑你将增加的索引是否是已有的多列索引的最左前缀。如果是这样的,不用增加索引,因为已经有了(例如,如果你在state、city和zip上建立了索引,那么没有必要再增加state的索引)。

让索引类型与你所执行的比较的类型相匹配。在你建立索引的时候,大多数存储引擎会选择它们将使用的索引实现。例如,InnoDB通常使用B树索引。MySQL也使用B树索引,它只在三维数据类型上使用R树索引。但是,MEMORY存储引擎支持散列索引和B树索引,并允许你选择使用哪种索引。为了选择索引类型,需要考虑在索引数据列上将执行的比较操作类型:

· 对于散列(hash)索引,会在每个数据列值上应用散列函数。生成的结果散列值存储在索引中,并用于执行查询。散列函数实现的算法类似于为不同的输入值生成不同的散列值。使用散列值的好处是散列值比原始值的比较效率更高。散列索引用于执行=或<=>操作等精确匹配的时候速度非常快。但是对于查询一个值的范围效果就非常差了:

id < 30

weight BETWEEN 100 AND 150

· B树索引可以用于高效率地执行精确的或者基于范围(使用操作<、<=、=、>=、>、、!=和BETWEEN)的比较。B树索引也可以用于LIKE模式匹配,前提是该模式以文字串而不是通配符开头。

如果你使用的MEMORY数据表只进行精确值查询,散列索引是很好的选择。这是MEMORY表使用的默认的索引类型,因此你不需要特意指定。如果你希望在MEMORY表上执行基于范围的比较,应该使用B树索引。为了指定这种索引类型,需要给索引定义添加USING BTREE。例如:

CREATE TABLE lookup

(

id INT NOT NULL,

name CHAR(20),

PRIMARY KEY USING BTREE (id)

) ENGINE = MEMORY;

如果你希望执行的语句的类型允许,单个MEMORY表可以同时拥有散列索引和B树索引,即使在同一个数据列上。

有些类型的比较不能使用索引。如果你只是通过把值传递到函数(例如STRCMP())中来执行比较操作,那么对它进行索引就没有价值。服务器必须计算出每个数据行的函数值,它会排除数据列上索引的使用。

使用慢查询(slow-query)日志来识别执行情况较差的查询。这个日志可以帮助你找出从索引中受益的查询。你可以直接查看日志(它是文本文件),或者使用mysqldumpslow工具来统计它的内容。如果某个给定的查询多次出现在“慢查询”日志中,这就是一个线索,某个查询可能没有优化编写。你可以重新编写它,使它运行得更快。你要记住,在评估“慢查询”日志的时候,“慢”是根据实际时间测定的,在负载较大的服务器上“慢查询”日志中出现的查询会多一些。

篇4:优化Mysql数据库的8个方法

-06-06mysql删除重复记录语句的方法

-05-05在Windows主机上定时备份远程VPS(CentOS)数据的批处理

-03-03免安转MySQL服务的启动与停止方法

-01-01mysql远程登录出错的解决方法

2011-09-09mysql error:#1062 Duplicate entry ‘***′ for key 1问题解决方

2012-11-11命令行模式下备份、还原 MySQL 数据库的语句小结

2010-03-03通过mysql show processlist 命令检查mysql锁的方法

-12-12MySQL 加密/压缩函数

-03-03在MySQL中修改密码及访问限制的设置方法详解

-11-11MySQL存储过程使用实例详解

篇5:优化Mysql数据库的8个方法

最近更 新

深入JDBC sqlserver连接写法的详解

从一个MySQL的例子来学习查询语句

简单实现MySQL服务器的优化配置方法

MySQL无法启动几种常见问题小结

Mysql建表与索引使用规范详解

MySQL5.6基本优化配置

mysql 常用命令集锦[绝对精华]

基于ubuntu中使用mysql实现opensips用户认

linux下mysql提示"mysql deamon fai

MySQL优化之如何查找SQL效率低的原因

热 点 排 行

mysql安装图解 mysql图文安装教程

超详细mysql left join,right jo

Can''t connect to MySQL server

Mysql命令行导入sql数据

MYSQL 数据库导入导出命令

Mysql字符串截取函数SUBSTRING的

MySQL数据库备份与恢复方法

MySQL server has gone away 问题

windows下mysql忘记root密码的解

MySQL日期数据类型、时间类型使用

篇6:网站站内优化几点分析

当我们的博客或者是网站上线之后我们需要做哪些工作呢?可能很多人一下子就没有一个思路就会感到手足无措,不知道从何下手,其实在我们网站上线之后我们的首要任务就是要把网站站内优化做好,因为良好的站内结构是网站保持良好收录的先决条件,同时也一定程度影响到用户体验,网站的站内优化包括很多方面,网站结构,关键词的分布,url的设置,内容的更新这些都是网站站内优化的范畴,

网站结构和关键词分布

关于站内结构的选择和设置在前面的博文中也有提到过,如何来选择可以根据自己的实际情况来选择自己合适的方式。

这里就简单说一下关键词的分布,关键词是我们做seo的重点之处,往往一个小型网站的关键词可能就几十个,而一个大中型网站的关键词可能就有成百上千个,这个时候没有一个合理的规划是一件非常头痛的问题,对于关键词的分布我们要按照关键词的竞争程度和我们自己所要优化的重点关键词依次分布在网站的首页》一级分类》二级栏目页》文章页(按照页面权重高低排序)之中。这样更有利于我们网站优化工作的展开,同时我们要明白的是网站的首页往往是权重最高的,我们应该减少不必要的权重导出,而竟可能的导向我们需要优化的页面,比如对于收录困难的栏目一个首页链接往往能够起到很好的效果,同时我们也要善用nofollow标签来控制网站的权重导向,

(这个以后再来给大家分享)

url的设置和内容更新

网站的url应该是站内优化中一个细节,之前提到的url标准化就是一个细节的问题,对于我们的url可以尽量的简单并且不要出现*¥%等等这样的特殊符号,最好是包含我们所要优化的关键字(对于谷歌来说效果不错)。并且url的长度最好不要过长,这样对于用户体验是非常不好的。

关于网站内容的更新就是一个非常重要的环节了,也是网站站内优化必不可少的一个环节,我们都知道对于搜索引擎来说肯定是希望能够有高质量的内容才能够吸引蜘蛛来抓去你的网站,所以原创文章就是最好的饲料,如果我们能够每天定时的给蜘蛛喂养高质量的好饲料,它肯定也不会亏待你。久而久之蜘蛛也会形成习惯在固定的时间来抓去你的文章,这样是最好的效果。像文刀木水自己的博客也是每天都会在固定的时间更新原创文章来进行内容的更新。

总结

当然站内优化还包括一些小的细节相信我们都有所了解,这里就不再多说了,讲了一些网站站内优化主要的方面。最后要总结的一点是要有好的执行力,并且能够坚持下来那么你就一定就能够做得更好。

首发 www.nttpy.com/articledetail-16.html

篇7:网站优化之网站地图

相比对于网站地图大家都不陌生,建站网站地图那是必须的,不管是对于搜索引擎还是用户体验来说都是很重要的,有了网站地图搜索引擎和用户就可以清晰的了解到这个网站的内容以及能给用户提供什么服务等,网站地图就像是黑夜中的萤火虫一样,能给我们指明方向,所以网站地图的重要性可想而知,

但还是有很多人都忽略了这一环节,在她们看来网站地图就是多余的,放不放都无所谓似的。自从今年搜索引擎多次改变算法以来笔者发现搜索引擎对于网站地图这块是越来越重视了,今天我们就来一起探讨下如何制作网站地图和如何优化设置网站地图:

一、教你制作网站地图

可能大家想来网站地图制作肯定很难,很多都会认为我不会代码怎么制作呢。其实会不会代码都没有关系,下面我为大家说下几种制作网站地图的方法,第一如果自己会代码,那自主编写一个就非常简单。第二在线地图制作,如果你不会代码,可以在搜索引挚中搜索一下在线网站地图制作工具,现在有很多这方面的工具,第三利用谷歌在线创建网站地图,目前谷歌支持多种形多的地图,同时咱们可以不用自己写代码,而且制作出来的地图更符合搜索引挚爬行。因此,对于地图的制作方法有简单的也有困难的,不管你懂不懂代码、会不会写代码都可以自主的创建地图,正所谓条条大路通罗马。

二、如何优化设置网站地图

上面我们说了如何制作网站地图,制作网站地图的方法也很简单,想必大家没有任何问题,

接下来我们来看下该如何放置网站地图,把它放在什么位置比较合适更有利于搜索引擎的爬行。

首先地图必须使用纯文字作导航。网站地图主要是给搜索引挚看的,所以不必弄得太过花哨,毕竟用户肯定不会知道网站地图是什么玩意。网站地图要简单、干净,以纯文字的形式作每条链接的锚文本。

其次网站地图需要每天生成更新。一般的网站地图都是以静态生成页面显示的,因为网站地图不需要24小时全天更新,况且地图更新过于频繁对SEO 优化也不好,毕竟一个静态页面经常更新内容让搜索引挚怎么看待呢?所以,网站地图只需要每天更新生成一次就行了,同时主要针对搜索引挚的网站地图把地图提交到各大搜索引挚一次即可,不要过于频繁的提交,那样也不利于SEO优化。

最后把地图提交给搜索引挚爬行。虽然很多站长都制作好地图并且把地图的SEO处理非常好,但是对于SEO优化中地图的作用,最重要一步就是提交网站地图,咱们可以这样来提交网站地图让搜索引挚更快爬行自己的站点,可以把网站地图的链接插入ROBOTS文件中,写法如下:

User-agent: *

Allow:

Sitemap:www.****.com/Sitemap.xml

看了以上几点相比大家对于网站地图已经是很了解了,从制作网站地图到放置网站地图最后在提交给搜索引擎完成这三步骤可以说是没有任何的难度,说的夸大点只要会上网就能搞定一个网站的地图。虽说网站地图它做起来简单,但他的重要性我们绝对不能忽视。

篇8:经典MySQL的limit查询优化数据库教程

以下的文章主要是对MySQL limit查询优化的具体内容的介绍,我们大家都知道MySQL数据库的优化是相当重要的,其他最为常用也是最为需要优化的就是limit。MySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。

同样是取10条数据

select * from yanxue8_visit limit 10000,10select * from yanxue8_visit limit 0,10

就不是一个数量级别的。

网上也很多关于limit的五条优化准则,都是翻译自MySQL手册,虽然正确但不实用。今天发现一篇文章写了些关于limit优化的,很不错。

文中不是直接使用limit,而是首先获取到offset的id然后直接使用limit size来获取数据。根据他的数据,明显要好于直接使用limit。这里我具体使用数据分两种情况进行测试。(测试环境win2033+p4双核 (3GHZ) +4G内存MySQLlimit查询)

1、offset比较小的时候

1.select * from yanxue8_visit limit 10,10

多次运行,时间保持在0.0004-0.0005之间

Select * From yanxue8_visit Where vid >=(Select vid From yanxue8_visit Order By vid limit 10,1  ) limit 10

多次运行,时间保持在0.0005-0.0006之间,主要是0.0006

结论:偏移offset较小的时候,直接使用limit较优,

这个显然是子查询的原因。

2、offset大的时候

select * from yanxue8_visit limit 10000,10

多次运行,时间保持在0.0187左右

Select * From yanxue8_visit Where vid >=(Select vid From yanxue8_visit Order By vid limit 10000,1  ) limit 10

多次运行,时间保持在0.0061左右,只有前者的1/3。可以预计offset越大,后者越优。

以后要注意改正自己的limit语句,优化一下MySQL了

推荐人评论

MySQL的优化是非常重要的。其他最常用也最需要优化的就是limit。MySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。

以上的相关内容就是对MySQLlimit查询优化 的介绍,望你能有所收获。

篇9:笔试题:优化mysql数据库的方法

笔试题:优化mysql数据库的方法

优化mysql数据库的方法,(4分,多写多得)

(1).数据库设计方面,这是DBA和Architect的'责任,设计结构良好的数据库,必要的时候,去正规化(英文是这个:denormalize,中文翻译成啥我不知道),允许部分数据冗余,避免JOIN操作,以提高查询效率

(2).系统架构设计方面,表散列,把海量数据散列到几个不同的表里面.快慢表,快表只留最新数据,慢表是历史存档.集群,主服务器Read & write,从服务器read only,或者N台服务器,各机器互为Master

(3).(1)和(2)超越PHP Programmer的要求了,会更好,不会没关系.检查有没有少加索引

(4).写高效的SQL语句,看看有没有写低效的SQL语句,比如生成笛卡尔积的全连接啊,大量的Group By和order by,没有limit等等.必要的时候,把数据库逻辑封装到DBMS端的存储过程里面.缓存查询结果,explain每一个sql语句

(5).所得皆必须,只从数据库取必需的数据,比如查询某篇文章的评论数,select count(*) ... where article_id = ? 就可以了,不要先select * ... where article_id = ?然后msql_num_rows.

只传送必须的SQL语句,比如修改文章的时候,如果用户只修改了标题,那就update ... set title = ? where article_id = ?不要set content = ?(大文本)

(6).必要的时候用不同的存储引擎.比如InnoDB可以减少死锁.HEAP可以提高一个数量级的查询速度

优化MySQL数据库性能的八大“妙手”MySQL综合

Apache+PHP+MySQL建立数据库驱动的动态网站

正确理解Mysql中的列索引和多列索引

网站SEO优化之关键词与长尾关键词

怎样选择关键词?网站优化从关键词分析开始!

空管班组的建设和优化分析

大型网站搜索行为和关键词分析

建立谷歌分析与网站优化工具跨域跟踪

基于RS和GIS的九寨沟景观格局动态分析

教育学视域下之教育现代化和教育研究现代化动态关系

《加速动态网站之MySQL索引分析和优化数据库(推荐9篇).doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

最新推荐
猜你喜欢
点击下载本文文档