仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 875|回复: 18
打印 上一主题 下一主题

[学习教程] PHP网页设计减速静态网站 MySQL索引剖析和优化

[复制链接]
兰色精灵 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-4 00:00:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
基础这个东西是个比较笼统的概念,如果你之前学习过c语言, c语言被认为是   <P style="TEXT-INDENT: 2em">本文次要讲述了若何减速静态网站的MySQL索引剖析和优化。 <P style="TEXT-INDENT: 2em">1、甚么是索引? <P style="TEXT-INDENT: 2em">索援用来疾速地寻觅那些具有特定值的纪录,一切MySQL索引都以B-树的模式保留。假如没有索引,履行查询时MySQL必需从第一个纪录入手下手扫描全部表的一切纪录,直至找到合适请求的纪录。内外面的纪录数目越多,这个操作的价值就越高。假如作为搜刮前提的列上已创立了索引,MySQL无需扫描任何纪录便可敏捷失掉方针纪录地点的地位。假如表有1000个纪录,经由过程索引查找纪录最少要比按次扫描纪录快100倍。 <P style="TEXT-INDENT: 2em">假定咱们创立了一个名为people的表: <P style="TEXT-INDENT: 2em">
  1.    CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );
复制代码
  <P style="TEXT-INDENT: 2em">然后,咱们完整随机把1000个分歧name值拔出到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处置的纪录数目越少,则它完成义务的速度就越快。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">2、索引的类型 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">MySQL供应多种索引类型供选择: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">通俗索引 : <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这是最根基的索引类型,并且它没有独一性之类的限制。通俗索引可以经由过程以下几种体例创立: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">创立索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">修正表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">创立表的时分指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) ); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">独一性索引: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这类索引和后面的“通俗索引”根基不异,但有一个区分:索引列的一切值都只能呈现一次,即必需独一。独一性索引可以用以下几种体例创立: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">创立索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">修正表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">创立表的时分指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) ); <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">主键 : <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">主键是一种独一性索引,但它必需指定为“PRIMARY KEY”。假如你已经用过AUTO_INCREMENT类型的列,你能够已熟习主键之类的概念了。主键普通在创立表的时分指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。然而,咱们也能够经由过程修正表的体例到场主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每一个表只能有一个主键。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">全文索引: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">MySQL从3.23.23版入手下手撑持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或TEXT类型的列上创立。它可以经由过程CREATE TABLE号令创立,也能够经由过程ALTER TABLE或CREATE INDEX号令创立。关于大范围的数据集,经由过程ALTER TABLE(或CREATE INDEX)号令创立全文索引要比把纪录拔出带有全文索引的空表更快。本文上面的会商不再触及全文索引,要懂得更多信息,请拜见MySQL documentation。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">3、单列索引与多列索引 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">索引可所以单列索引,也能够是多列索引。上面咱们经由过程详细的例子来讲明这两种索引的区分。假定有如许一个people表: <P style="TEXT-INDENT: 2em">
  1. 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) );
复制代码
<P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">上面是咱们拔出到这个people表的数据: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这个数据片断中有四个名字为“Mikes”的人(个中两个姓Sullivans,两个姓McConnells),有两个岁数为17岁的人,还有一个名字不同凡响的Joe Smith。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这个表的次要用处是依据指定的用户姓、名和岁数前往响应的peopleid。例如,咱们能够需求查找姓名为Mike Sullivan、岁数17岁用户的peopleid(SQL号令为SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。因为咱们不想让MySQL每次履行查询就去扫描全部表,这里需求思索应用索引。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">起首,咱们可以思索在单个列上创立索引,好比firstname、lastname或age列。假如咱们创立firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL将经由过程这个索引敏捷把搜刮局限限制到那些firstname='Mike'的纪录,然后再在这个“两头了局集”长进行其他前提的搜刮:它起首扫除那些lastname不等于“Sullivan”的纪录,然后扫除那些age不等于17的纪录。当纪录知足一切搜刮前提以后,MySQL就前往终究的搜刮了局。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">因为创立了firstname列的索引,与履行表的完整扫描比拟,MySQL的效力进步了良多,但咱们请求MySQL扫描的纪录数目仍然远远超越了实践所需求的。固然咱们可以删除firstname列上的索引,再创立lastname或age列的索引,但总地看来,不管在哪一个列上创立索引搜刮效力仍然类似。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">为了进步搜刮效力,咱们需求思索应用多列索引。假如为firstname、lastname和age这三个列创立一个多列索引,MySQL只需一次检索就可以够找出准确的了局!上面是创立这个多列索引的SQL号令: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age); <P style="TEXT-INDENT: 2em">因为索引文件以B-树格局保留,MySQL可以当即转到适合的firstname,然后再转到适合的lastname,最初转到适合的age。在没有扫描数据文件任何一个纪录的情形下,MySQL就准确地找出了搜刮的方针纪录! <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">那末,假如在firstname、lastname、age这三个列上分离创立单列索引,后果是不是和创立一个firstname、lastname、age的多列索引一样呢?谜底是不是定的,二者完整分歧。当咱们履行查询的时分,MySQL只能利用一个索引。假如你有三个单列的索引,MySQL会试图选择一个限制最严厉的索引。然而,即便是限制最严厉的单列索引,它的限制才能也一定远远低于firstname、lastname、age这三个列上的多列索引。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">4、最左前缀 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">多列索引还有别的一个长处,它经由过程称为最左前缀(Leftmost Prefixing)的概念表现出来。持续思索后面的例子,如今咱们有一个firstname、lastname、age列上的多列索引,咱们称这个索引为fname_lname_age。当搜刮前提是以下各类列的组应时,MySQL将利用fname_lname_age索引: <P style="TEXT-INDENT: 2em">
  1. firstname,lastname,agefirstname,lastnamefirstname
复制代码
<P style="TEXT-INDENT: 2em">从另外一方面了解,它相当于咱们创立了(firstname,lastname,age)、(firstname,lastname)和(firstname)这些列组合上的索引。上面这些查询都可以利用这个fname_lname_age索引: <P style="TEXT-INDENT: 2em">
  1.    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';
复制代码
<P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">5、选择索引列 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">在功能优化过程当中,选择在哪些列上创立索引是最主要的步调之一。可以思索利用索引的次要有两品种型的列:在WHERE子句中呈现的列,在join子句中呈现的列。请看上面这个查询: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">
  1. SELECT age ## 不利用索引FROM people WHERE firstname='Mike' ## 思索利用索引AND lastname='Sullivan' ## 思索利用索引
复制代码
<P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这个查询与后面的查询略有分歧,但仍属于复杂查询。因为age是在SELECT局部被援用,MySQL不会用它来限制列选择操作。因而,关于这个查询来讲,创立age列的索引没有甚么需要。上面是一个更庞杂的例子: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">
  1.    SELECT people.age, ##不利用索引town.name ##不利用索引FROM people LEFT JOIN town ONpeople.townid=town.townid ##思索利用索引WHERE firstname='Mike' ##思索利用索引AND lastname='Sullivan' ##思索利用索引
复制代码
<P style="TEXT-INDENT: 2em">与后面的例子一样,因为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';”这个查询不会利用索引。
应该大致熟悉了一些学习过程,也许我的过程和你的有些出路,但是不管怎么样是殊途同归,我写这么多,也只是给大家一个借鉴的机会,至于好与不好,默默不敢打包票^0^
金色的骷髅 该用户已被删除
沙发
发表于 2015-2-4 08:00:05 | 只看该作者
说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。
再见西城 该用户已被删除
板凳
发表于 2015-2-6 16:07:44 | 只看该作者
Ps:以上纯属原创,如有雷同,纯属巧合
灵魂腐蚀 该用户已被删除
地板
发表于 2015-2-15 09:39:38 | 只看该作者
写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。
简单生活 该用户已被删除
5#
发表于 2015-2-23 09:28:39 | 只看该作者
真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,
爱飞 该用户已被删除
6#
发表于 2015-3-12 12:09:54 | 只看该作者
因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax
山那边是海 该用户已被删除
7#
发表于 2015-3-12 19:24:51 | 只看该作者
在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。
不帅 该用户已被删除
8#
发表于 2015-3-20 01:49:20 | 只看该作者
有位前辈曾经跟我说过,phper 至少要掌握200个函数 编起程序来才能顺畅点,那些不熟悉的函数记不住也要一拿手册就能找到。所以建议新手们没事就看看php的手册(至少array函数和string函数是要记牢的)。
飘灵儿 该用户已被删除
9#
发表于 2015-3-25 07:06:32 | 只看该作者
遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。
活着的死人 该用户已被删除
10#
发表于 2015-3-29 12:55:01 | 只看该作者
本文当是我的笔记啦,遇到的问题随时填充
兰色精灵 该用户已被删除
11#
 楼主| 发表于 2015-4-6 22:09:56 | 只看该作者
兴趣是最好的老师,百度是最好的词典。
小魔女 该用户已被删除
12#
发表于 2015-4-11 00:56:11 | 只看该作者
我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能:
第二个灵魂 该用户已被删除
13#
发表于 2015-4-13 15:56:24 | 只看该作者
实践是检验自己会不会的真理。
莫相离 该用户已被删除
14#
发表于 2015-4-13 22:52:08 | 只看该作者
首先我是坚决反对新手上来就用框架的,因为对底层的东西一点都不了解,造成知识上的真空,会对以后的发展不利。我的观点上手了解下框架就好,代码还是手写。当然啦如果是位别的编程语言的高手的话,这个就另当别论啦。
分手快乐 该用户已被删除
15#
发表于 2015-4-17 01:45:38 | 只看该作者
作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
谁可相欹 该用户已被删除
16#
发表于 2015-5-9 10:28:10 | 只看该作者
不禁又想起那些说php是草根语言的人,为什么认得差距这么大呢。
蒙在股里 该用户已被删除
17#
发表于 2015-5-9 14:34:59 | 只看该作者
使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。
深爱那片海 该用户已被删除
18#
发表于 2015-5-10 18:34:39 | 只看该作者
使用zendstdio 写代码的的时候,把tab 的缩进设置成4个空格是很有必要的
小女巫 该用户已被删除
19#
发表于 2015-5-10 20:31:48 | 只看该作者
兴趣是最好的老师,百度是最好的词典。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 21:43

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表