前端优化 css同类型合并--压缩-图片压缩-缓存-js压缩等php
https://www.zhihu.com/question/21658448 http://www.cnblogs.com/fangshidaima/p/5823465.htmlcss
后端优化 php引号-foreach-算法-函数实现方法比对(运行时间测试修改)html
数据库优化(大数据优化) 索引-字段类型-位数-引擎前端
服务器优化 html5
数据传输优化 json格式 php系列化(serialize)java
seo优化nginx
redisgit
安全 数据过滤,验证,加密github
http://www.tp-shop.cn/index.php/doc/indexbbc/videoweb
网站高并发架设
这些技术不必定要所有用上
浏览器开启压缩存储
1,php开启压缩存储
j2) LocalStorage
LocalStorage是html5的一个新技术,可用于本地缓存。本技术只对支持html5的浏览器使用,若是要向下兼容,能够经过ajax异步经过Redis、Memcache等写入服务器的内存。
在什么地方能够查看呢?打开谷歌浏览器Chrome 按F12 点击Resources(参考图:demo\chapter1\demo2 \1-2.png)
3图片优化合并为一张
尽可能少请求
必定要都用到知道的最优化方式,每一个快个几百毫秒,一个大项目,几万行代码下了
就快了多少这样,特别是大数据,几亿数据遍历那样快了不知道多了都,
一个代码块实现有不少种方法,多测试,看看哪一种速度最快,测试多了,积累经验,就能写出高效的代码
php官方提供的
http://www.jb51.net/article/29065.htm
http://pear.php.net/package/Benchmark/download
$arr[id] = 0;//The Case 1 is annotated this line 0.0071161985397339
$arr['id'] = 0;//The Case 1 is annotated this line 0.00069479942321777
能在客户端浏览器处理的尽可能在客户端处理,不要在服务器,这样能节省网络开销等
经过比对php代码执行的时间
Javascript
php代码优化部分
第一章:程序优化部分(PHP/JavaScript)
1 Jacascript 部分
2 php 开发习惯
1.你们要记住一个原则,“能用JavaScript实现的就不要用PHP去实现”,其实质就是减小在服务器端运行程序。
1) Cookie
在安全性要求不高的地方,能够用JS(后面咱们就用JS来代替JavaScript)实现Cookie的读取。好比:记录网友的浏览足迹,商城中未登陆用户把产品添加进购物车等,这些操做没有必要写入数据库。
演示Js操做Cookie的例子…
这里有个美中不足的地方就是Cookie的大小是有限制的(参考图:demo\chapter1\demo1 \1-1.png),这也是为了安全须要而限定的。在这里我给你们介绍另外一个技术:LocalStorage
2) LocalStorage
LocalStorage是html5的一个新技术,可用于本地缓存。本技术只对支持html5的浏览器使用,若是要向下兼容,能够经过ajax异步经过Redis、Memcache等写入服务器的内存。
在什么地方能够查看呢?打开谷歌浏览器Chrome 按F12 点击Resources(参考图:demo\chapter1\demo2 \1-2.png)
LocalStorage可支持的大小能够参考图:demo\chapter1\demo2 \1-3.png
3)Ajax
a.尽可能Ajax去代替提交表达,避免刷新页面。(Ajax不在本课程讲解范围)
b.PHP和Js直接的最佳的通讯方式就是json,尽可能避免传递html格式的字符串。
2.PHP方面的优化细节
1) $row['id'] =0比 $row[id]=0 快,次数越大越明显/生产环境(Linux)下测试1个数量级;
2) 递增递减
a.递增(递减)一个预预约义的局部变量要比递增(递减)一个未定义的局部变量快;差异较大
b.执行变量$i的递增(递减)时,++$会比$i++快一些;这种差别是PHP特有的,并不适用于其余语言;差异较小
3) 在可行的状况下,避免使用正则表达式,str_replace 函数比 preg_replace,差异仍是很明显的;
4) include 文件时尽可能使用绝对路径,由于它避免了 PHP 去 include_path 里查找文件的速 度,解析操做系统路径所需的时间会更少;差异不太明显
5) 用单引号(’’)代替双引号(””),单引号为强类型,将其中的因此字符都认做字符,而双引号的为弱类型,它会检测其中是否存在变量,测试差异不大
6) 避免使用“@”,早先测试的差异较大,本次测试的差异不大,应该是跟版本、系统等环境有关系
7) 在有必要的时候使使用引用(&),此处借鉴了C 语言的指针,测试差异较大,接近1个数量级
8) 尽可能用include代替include_once,由于include_once多了一些检测,差异应该不大,此处部分用屡次循环模拟。
9)for 和foreach;生产环境(Linux)下测试:foreach($row as &$v)略快于for($i = 0 ;$i < 10000; $i++);foreach($row as $k=>$v)最慢
10)判断字符串长度时,可用isset($str{15})代替strlen($str) < 15;由于isset()做为一种语言结构,而strlen()是函数,语言结构快于函数;
11) $n += $i 快于$n = $n + $i;测试差异不大
12) Apache 处理 PHP 脚本的速度要比静态页面慢 2-10 倍,所以尽可能采用多的静态页面,少的脚本;PHP程序使用文件缓存性能会倍增;
13) 获取Unix时间戳时用$_SERVER['REQUEST_TIME'] 代替time(); wamp环境测试性能提示20~30%/Linux生产环境测试性能提高 500% (5倍)
14) $_SERVER['DOCUMENT_ROOT']代替str_replace('//','/',dirname(__FILE__) .'/');wamp测试无太大差异/Linux生产环境测试性能提高 500% (5倍)
15) 若是能将类的方法定义成 static,就尽可能定义成 static,性能会有提示;测试差异不是不少;
16) 用Mysqli或pdo代替Mysql
18) 通常不建议启用auto_start(session.auto_start:是否自动启用) ,由于建立Session须要消耗系统资源,咱们一般只会在须要用到Sesson时,才会使用session_start函数来开启Session功能。
19)直接将成员变量定义成共有并直接复制比经过方法向私有变量赋值效率高2~3倍,即提高200%~300%,但这跟违背了封装的风格,你们可自行决定;
last)尽可能采用PHP内置函数
原生PHP代码是性能最高的,但用原生PHP开发网站,效率会低不少;任何的php框架,框架自己都会消耗必定的资源。
文件ob缓存静态html(解决php每访问一次解析一次,直接html,
十万篇文章,十万个用户,每一个用户访问文章,这就是十万次数据库的读取,咱们把他写出文件的静态缓存,大大的减小了服务器的开销
,
)
Opcache高并发中很重要(Opcache扩展要开启
例如框架,它是个单一入口,在请求框架单一入口时,会请求不少,好比会初始化一些常量,一些变量文件,初始化配置文件,初始化语言包,初始化函数库,初始化数据库链接等等,
假设这些有1万行代码,假设高并发中有1万个用户请求,那么php解析器逐行解析1万行,万*万就是1亿,用了Opcache就不用解析了,高效的提升
)
redis缓存(一个网站,用户访问,就要产生几十条数据库语句,假设10万个用户访问,那么几十*10万,就是几百万查询数据库了,对数据库很大开销。假如把分类,商店公告,站内快讯,产品列表,抢购页面,像这些不可能每次都去查询数据库,像这种状况,咱们会把它们存到redis数据库,下次操做,直接从redis读取,这样减小了几十条数据查询,当用户成千上万时,就能够少了多少数据库语句了,这些都是能够算一下的)
===========
头部 header.php 要缓存的php,上面引入它 定义缓存过时时间
<?php
define('CACHE_EXPIRE',1800);
define('CACHE_PATH',$_SERVER['DOCUMENT_ROOT'].'/cache/');
define('REFRESH_EXPIRE',10);
is_dir(CACHE_PATH) or mkdir(CACHE_PATH,0777);
function refreshTimes(){
$currentUrl='http://'.$_SERVER["HTTP_HOST"].$_SERVER['REQUEST_URI'];
if(isset($_COOKIE['refreshTimes'])){
$cookArray=explode("\t",$_COOKIE['refreshTimes']);
if(isset($cookArray[1]) and $_SERVER['REQUEST_TIME'] - (int)$cookArray[1] < REFRESH_EXPIRE and isset($cookArray[0]) and $cookArray[0] == $currentUrl){
setcookie('refreshTimes',$currentUrl."\t".$_SERVER['REQUEST_TIME']."\t".(string)((int)$cookArray[2]+1),0,'/');
return (int)$cookArray[2];
}else{
setcookie('refreshTimes',$currentUrl."\t".$_SERVER['REQUEST_TIME']."\t1",0,'/');
return 0;
}
}else{
setcookie('refreshTimes',$currentUrl."\t".$_SERVER['REQUEST_TIME']."\t1",0,'/');
return 0;
}
}
$key = md5($_SERVER['REQUEST_URI']);
$path = CACHE_PATH.$key;
if(is_file($path)
and filemtime($path)+CACHE_EXPIRE > $_SERVER['REQUEST_TIME']
and refreshTimes() == 0
){
readfile($path);
exit();
}
ob_start();
?>
<?php
include 'head.php';
$title = "Hello world~";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title><?php echo $title?></title>
</head>
<body>
<?php
echo "你好,欢迎访问本站~~~~$$";
?>
</body>
</html>
<?php
include 'foot.php';
?>
====
foot.php
<?php
$html = ob_get_contents();
ob_clean();
file_put_contents($path,$html);
echo $html;
?>
上面代码用 下面2个函数,抓取地址保存为html,不保存时间,修改时,同时在执行下这代码,就能够了
File_put_contents
file_get_contents
readfile读取文件效率最高
相对来讲,java程序执行效率比较高,php每访问编译一次。把其缓存起来就比较快了
Rredis
文件缓存
Opcache
1.文件缓存
文件缓存是一种最多见,最方便实现的一种缓存方式,使用这种可使网站的并发量获得显著的提升。若是你的网站只是购买的FTP空间,没有权限去修改PHP的设置,选择这种方法是最好的选择。
2.php的opcache缓存
) 在正式的生成环境中,必定要使用一块OPcode缓存插件
参考图:2-1
若是在编译安装的时候没有开启此选项也没有关系,咱们能够以安装扩展的形式来安装:
参考图:2-2
安装步骤:
# cd php-5.6.3/ext/opcache
# /usr/local/php/bin/phpize
# ./configure --with-php-config=/usr/local/php/bin/php-config
# make && make install
##安装成功,查看一下
# ll /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
而后在php.ini文件中开启便可,关于opcache的选项共有27个(不包括指定扩展文件的选项zend_extension=opcache.so ),都有默认值
相关配置能够参考官方文档:
http://php.net/manual/zh/opcache.configuration.php
配置以下:
[opcache]
;指定对应的扩展文件(此项是惟一一个必须的选项)
zend_extension=opcache.so
什么是CLI模式:
# /usr/local/php/bin/php -r "echo \"hello world\n\";"
# /usr/local/php/bin/php -r "phpinfo();"
关于参数 –r 你们能够查看帮助信息:
/usr/local/php/bin/php –h
讲解完毕演示效果
官网的一段推荐设置:
http://php.net/manual/zh/opcache.installation.php
注释:此方法在开发环境中不建议使用,会给开发者带来不便
3使用.redis进行缓存:
网站最大的瓶颈就是数据库部分,若是能把数据库中的数据读出来以后缓存到内存中,其性能将会有巨大的提高。
1) redis安装及配置
你们能够取他们的官网下载最新的稳定版:http://redis.io/
我这里采用的是:redis-3.0.1.tar.gz
# tar xf redis-3.0.1.tar.gz
# mv redis-3.0.1 /usr/local/redis
# cd /usr/local/redis/
# make
安装完成…
# vim redis.conf
daemonize no 改成:daemonize yes(后台运行)
这里有个service启动脚本:
# cp ~/redis.service /etc/init.d/redis
# chmod +x /etc/init.d/redis
# chkconfig redis on
# chkconfig --list redis
redis 0:off 1:off 2:on 3:on 4:on 5:on 6:off
设置为开机自动启动,启动redis
# service redis start
打开配置文件(redis.conf),找到下列行为其设置秘密:
# requirepass foobared
复制一行改成:
requirepass 888888
保存退出并重启
# service redis restart
打开客户端:
src/redis-cli
受权:
2)安装php的redis扩展:
(压缩安装包:owlient-phpredis-2.1.1-1-g90ecd17.tar.gz)
# wget https://codeload.github.com/owlient/phpredis/zip/master
# unzip master
# cd phpredis-master/
# /usr/local/php/bin/phpize
# ./configure --with-php-config=/usr/local/php/bin/php-config
# make && make install
查看一下:
# ll /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
配置php.ini文件
# vim /usr/local/php/lib/php.ini
双敲GG将光标移至最后增长一下部分:
[redis]
extension = redis.so
保存退出,重启php-fpm
# service php-fpm restart #nginx 服务器
# service httpd restart #apache服务器
在phpinfo()页面:
看到这跟说明大功告成。
测试程序:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1','6379');
$redis->auth('888888');
echo $redis->get('name');
$redis->set('name','b');
查询,高效的sql语句
索引/建表
服务器方面/主从复制
优化1查询一条数据 时加limit 1。
1.优化数据类型:
下面几个原则有助于作出更好的选择:
1) 更小的一般更好:
像VARCHAR类型的,虽然是变长存储,但读取到内存的时候,依然是定长的。
2)简单就好
简单的数据类型的操做一般须要更少的CPU周期。例如,整数比字符操做代价更低,由于字符集合校对规则(排序规则)使用字符比较比整数型比较更复杂。
3)尽可能避免NULL:
若是查询中包含可为NULL的列,对MySQL来讲更难优化,由于可为NULL的列使得索引、索引统计和值比较更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也须要特殊处理。当可为NULL的列被索引时,每一个索引记录须要一个额外的字节,在MyISAM里甚至还可能致使固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。
一般把可为NULL的列改成NOT NULL带来的性能提高比较小,索引(调优时)没有必要首先在现有的数据库中查找并修改掉这种状况,除非肯定这会致使问题,可是,若是计划在列上建索引,就应该尽可能避免设计成可为NULL的列。
2.VARCHAR和CHAR类型
注意:
VARCHAR:最大长度同TEXT(2^16-1=65535)类似,是:65532(Mysql 5.0.3以上版本)加上起始和结尾占去3个字节也是65535
CHAR:最大长度是255个字节;
1)VARCHAR
VARCHAR类型用于存储可变长字符串,是最多见的字符串数据类型。它比定长类型更节省空间,由于它仅使用必要的空间(例如,越短的字符串使用越少的空间)。
因为行是变长的,在UPDATE时可能使行变的比原来更长,这就致使须要作额外的工做。
2)CHAR
CHAR类型是定长的:
CHAR适合存储很短的字符串,或者全部值都接近同一个长度,例如MD5值(密码)。对于常常变动的数据,CHAR也比VARCHAR更好,由于CHAR类型不容易产生碎片。
有个地方须要注意:CHAR会自动截取掉字符串结尾的空格。
实验:
建立两个表格:
CREATE TABLE `char_test` ( `char_col` char(10));
CREATE TABLE `varchar_test` ( `char_col` varchar(10));
插入数据:
INSERT INTO `char_test`(`char_col`) VALUES('string1'),(' string2'),('string3 ');
INSERT INTO `varchar_test`(`char_col`) VALUES('string1'),(' string2'),('string3 ');
检索的时候会发现,VARCHAR类型的string3末尾的空格被截掉了。
SELECT CONCAT("'",`char_col`,"'") FROM `char_test`;
SELECT CONCAT("'",`char_col`,"'") FROM `varchar_test`;
执行结果以下图:
提示:慷慨是不明智的
使用VARCHAR(5)和VARCHAR(200)存储’hello’的空间开销是同样的。那么短的列有什么优点吗?
事实证实有很大的优点。更长的列会消耗更多的内存,由于MySQL一般会分配固定大小的内存块来保存内部值。尤为是使用内存临时表进行排序或操做时会特别糟糕。在利用磁盘临时表进行排序时也一样糟糕。
全部最后的策略是只分配真正须要的空间。
索引
什么是索引?
咱们先来讲一下分表。经常使用的分表有横向切分和纵向切分,咱们今天就来讲一下表格的纵向切分。好比咱们要作一个资讯系统,首先咱们要设计存储文件的表格,好比须要的字段有:主键ID、表格title、文章类别ID、来源、发布时间、访问次数、概述、文章内容。最多见的分法就是内容放一个表格里(包含文章内容和一个主键)、其余部分放在一个表里,能够做为主表,经过主表的主机递增产生一个ID,将这个ID和内容存入内容表中。
若是数据超过了1000万条,内容表的至少都在1个G以上,而主表大小通常也就300M到500M之间。就文章列表页而言,想一下扫描一个三五百兆的文件和扫描一个几个跟G的文件那个快?这种分表的方式就是借鉴了索引的特色,这样你们就应该明白索引是怎么回事了吧。
索引主要的三个有点:
1) 索引大大减小了服务器须要扫描的数据量。
2) 索引能够帮助服务器避免排序和临时表。
3) 索引能够讲随机I/O变为顺序IO。
实验:有索引和没有索引的区别
下面这跟表是我几年前我在某分类信息网上经过一个php程序采集的一些用户的信息如手机号码等,表内数据共2509793条:
SELECT COUNT(*) FROM tb_test2;
SELECT COUNT(*) FROM tb_test1;
我将表tb_test1复制了一份为tb_test2,而后去掉了其主键索引,咱们测试一下查询速度,以下所示:
SELECT name,mobel,eMail,address FROM tb_test2 WHERE urlID=1888\G
SELECT name,mobel,eMail,address FROM tb_test1 WHERE urlID=1888\G
咱们看一下有索引和没有索引各自检索相应的记录所须要扫描的记录条数:
EXPLAIN SELECT name,mobel,eMail,address FROM tb_test1 WHERE urlID=1888\G
EXPLAIN SELECT name,mobel,eMail,address FROM tb_test2 WHERE urlID=1888\G
很显然,有索引的只需扫描一条便可,而没有索引的须要全表扫描。为何索引只扫描一条呢,其实有索引的只须要扫描整个索引就能够了,找到对应的指针能够直接定位到相应的数据,可能有的同窗要问了,第二个为何要扫描全表呢,搜索前1888条不就找到了么?那是由于数据库也不知道符合条件的有多少条,全部要对比全部数据,把全部符合条件的都找出来。
换一种查询方法看看:
SELECT name,mobel,eMail,address FROM tb_test2 ORDER BY urlID ASC LIMIT 1000,25;
SELECT name,mobel,eMail,address FROM tb_test1 ORDER BY urlID ASC LIMIT 1000,25;
看一下二者的区别:
语句解释:
EXPLAIN SELECT name,mobel,eMail,address FROM tb_test2 ORDER BY urlID ASC
LIMIT 1000,25\G
EXPLAIN SELECT name,mobel,eMail,address FROM tb_test1 ORDER BY urlID ASC
LIMIT 1000,25\G
覆盖索引:
一般你们都会根据查询的WHERE条件来建立合适的索引,不过这只是索引优化的一个方面。设计优秀的索引应该考虑到整个查询,而不仅仅是WHERE条件部分。索引确实是一种查找数据的高效方式,可是MySQL也看看有使用索引来直接获取列的数据,这样就再也不须要读取数据行。若是索引的叶子节点中已经包含要查询的数据,那么还有什么必要再回表查询呢?若是一个索引包含(或者说覆盖)全部须要查询的字段的值,咱们就称之为“覆盖索引”。
当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列能够看到“Using index”的信息。
对分页进行优化:
SELECT urlID,name,mobel,address FROM tb_test1 ORDER BY urlID ASC LIMIT 1000,10;
SELECT urlID,name,mobel,address FROM tb_test1 INNER JOIN(SELECT urlID FROM tb_test1 ORDER BY urlID ASC LIMIT 1000,10) AS uID USING(urlID);
咱们把第二种检索方法叫作延迟关联,由于延迟了对列的访问。在查询的第一阶段MySQL可使用覆盖索引,在FROM字句的查询中找到匹配的urlID,而后根据这些urlID值在外层查询匹配获取须要的列值。
各自扫描行数:
EXPLAIN SELECT urlID,name,mobel,address FROM tb_test1 ORDER BY urlID ASC LIMIT 1000,10\G
EXPLAIN SELECT urlID,name,mobel,address FROM tb_test1 INNER JOIN(SELECT urlID FROM tb_test1 ORDER BY urlID ASC LIMIT 1000,10) AS uID USING(urlID)\G
结尾
最后咱们讲一下EXPLAIN:EXPLAIN是用来获取关于查询执行计划的信息,以及如何解释输出的。EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法。这跟功能有局限性,并不总会说出真相,但它的输出是能够获取的最好信息,值得花时间了解,由于能够学习到查询是如何执行的。学会解释EXPLAIN将帮助你了解MySQL优化器是如何工做的。
EXPLAIN中的列:
EXPLAIN的输出老是有相同的列,可变的是行数及内容。下面咱们一块儿来学习EXPLAIN结果中每一列的意义。注意:输出中的行以MySQL实际执行的查询部分的顺序出现,而这跟顺序不老是与其在原始SQL中的相一致。
id列
这一列老是包含一个编号,标识SELECT所属的行。若是在语句当中没有子查询或联合,那么只会有惟一的SELECT,因而每一行在这跟列中都将显示一个1。不然内层的SELECT语句通常会顺序编号,对应于其在原始语句中的位置。
select_type列
这一列显示了对应行是简单仍是复杂的SELECT。SIMPLE值意味着查询不包括子查询和UNION。若是查询有任何复杂的子部分,则最外层部分标记为PRIMARY,其余部分标记以下。
SUBQUERY
包含在SELECT列表中的子查询中的SELECT(换句话说,不在FROM字句中)标记为SUBQUERY。
DERIVED
DERIVED值用来表示包含在FROM字句的子查询中的SELECT,MySQL会地柜执行并将结果放到一个临时表中。服务器内部称其“派生表”,所以该临时表是从子查询中派生出来的。
UNION
在UNION中的第二个和随后的SELECT被标记为UNION。第一个SELECT被标记就好像它以部分外查询来执行。这就是以前的例子中在UNION中的第一个SELECT显示为PRIMARY的缘由。若是UNION被FROM字句中的子查询包含,那么它的第一个SELECT会被标记为DERIVED。
UNION RESULT
用来从UNION的匿名临时表检索结果,SELECT被标记为UNION RESULT.
除了这些值,SUBQUERY和UNION还能够被标记为DEPENDENT和UNCACHABLE。 DEPENDENT意味着SELECT依赖于外层查询中发现的数据;UNCACHEABLE意味着SELECT中的某些特性阻止结果被缓存于一个Item_cache中。
table列
中一列显示了对应的正在访问的哪跟表,在一般状况下,它至关明了:它就是那跟表,或是该表的别名。
当FROM 子句中有子查询或有UNION时,table列会变得复杂的多,在这些场景下,确实没有一个“表”能够参考到,由于MySQL建立的匿名临时表仅在查询执行过程当中存在。此项你们了解一下就能够了,具体状况能够取参考一下相关资料,下面咱们来重点将一下type列。
type列
MySQL用户手册上说明这一列显示了“关联类型”,但咱们认为更准确的说法是访问类型,换言之就是MySQL决定如何查找表中的行。下面是最重要的访问方法,一次从最差到最优。
ALL
这就是人们所称的全表扫描,一般意味着MySQL必须扫描整张表,从头至尾,去找到须要的行。(这里也有跟例外,例如在查询里使用了LIMIT或者Extra列显示“Using distinct/not exists”。)
index
这个跟全表扫描同样,只是MySQL扫描表时按索引次序进行而不是行。它的主要优势是避免了排序;最大的缺点是要承担按索引次序读取整个表的开销。这一般意味着如果按随机次序访问行,开销将会很是大。
若是在Extra列中看到“Using index”,说明MySQL正在使用覆盖索引,它只扫描索引的数据,而不是按索引次序的每一行。它比按索引次序全表扫描的开销要少不少。
Range
范围扫描就是一个有限制的索引扫描,它开始于索引里的某一点,返回匹配这跟值域的行。这笔全索引扫描好一些,所以它用不着便利所有索引。显而易见的范围扫描是带有BWTWEEN或WHERE子句里带有>的查询。
当MySQL使用索引去查找一系列值时,例如IN()和OR列表,也会显示为范围扫描。然而,这二者实际上是至关不一样的访问类型,在性能上有重要的差别。
ref
这是一种索引访问,它返回全部的匹配某跟单个的值的行。然而它可能会找到多个符合条件的行,所以,它是查找和扫描的混合体。此类索引访问只有当使用非惟一性索引或者惟一性索引的非惟一性前缀时才会发生。把它叫作ref是由于索引要跟某跟参考值相比较。这跟参考值或者是一个常数,或者是来自多表查询前一个表里的结果值。
ref_or_null是ref之上的一个变体,它意味着MySQL必须在初次查找的结果李进行第二次查找,以找出NULL挑目录。
eq_ref
使用这种索引查找,MySQL知道最多只返回一个符合条件的记录。这种访问方法能够在MySQL使用主键或惟一性索引查找时看到,它会将它们与某跟参考值作比较。MySQL对于这类访问类型的优化作的很是好,由于它知道无须估计匹配行的范围或在找到匹配行后再继续查找。
const,system
当MySQL能对查询的某部分进行优化并将其转换成一个常量时,它就会使用这些访问类型。举例来讲,若是你经过将某一行的主键放入WHERE子句里的方式来选取此行的主键,MySQL就能把这个查询转换为一个常量。而后就能够高效地将表从链接执行中移除。
NULL
这种访问方式意味着MySQL能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。例如,从一个索引列里选取最小值能够经过单独查找索引来完成,不须要再执行时访问表。
possible_keys列
这一列显示了查询可使用哪些索引,这是基于查询访问的列和使用的比较操做符来判断的。这个列表是在优化过程的早期建立的,所以有些罗列出来的索引可能对于后续优化过程是没有用的。
key列
这一列显示了MySQL决定采用哪跟索引来优化对该表的访问。若是该索引没有出如今possible_keys列中,那么MySQL选用它是出于另外的缘由——例如,它可能选择了一个覆盖索引,哪怕没有WHERE子句。
换句话说,possible_keys揭示了哪个索引能有助于高效地进行查找,而key显示的是优化采用哪个索引能够最小化查询成本。
key_len列
该列显示了MySQL在索引里使用的字节数。若是MySQL正在使用的只是索引里的某些列,那么能够用这跟值来算出具体是哪些列。
ref列
这一列显示了以前的表在key列记录的索引中查找所用的列或常量。
row列
这一列是MySQL估计为了找到所需的行而要读取的行数。这个数字是内嵌循环关联计划里的循环数目。也就是说它不是MySQL认为它最终要从表里读取出来的行数,而是MySQL为了找到符合查询的每一点上标准的那些行而必须读取的行的平均数。
根据表的统计信息和索引的选用状况,这跟估算可能不是很准确。
Extra列
这一列包含的是不适合在其余列显示的额外信息。MySQL用户手册里记录了大多数能够在这里出现的值。
“Using index”
此值表示MySQL将使用覆盖索引,以免访问表。不用把覆盖索引和index访问类型弄混了。
“Using where”
这意味着MySQL服务器将存储引发检索行后再进行过滤。许多WHERE条件里涉及索引中的列,当它读取索引时,就能被存储引擎检验,所以不是全部带WHERE子句的查询都会显示“Using where”。有时”Using where”的出现就是一个暗示:查询可受益不一样的索引。
“Using temporary”
这意味着MySQL在对查询结果排序时会使用一个临时表。
“Using filesort”
这意味则会MySQL会对结果使用一个外部索引排序,而不是索引次序从表里读取行。
“Rang checked for each record(index map:N)”
这跟值意味着没有好用的索引,新的索引将在联接的每一行上从新估算。N是显示在possible_key列中索引的位图,而且是冗余的。
配置方面
服务器缓存
lvs负载均衡
web服务器集群,数据库读写分离,分表分库,缓存服务器,所有集体搭建配合工做
集群假设(负载均衡+缓存服务器+集群服务器+数据库服务器+keeplive心跳线)
加速cdn 消息队列排队原理
cpu调优
内存的调优