高併發網站架設

 

前端優化 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圖片優化合併爲一張

 

儘可能少請求

1、大綱

 

2、php程序優化

必定要都用到知道的最優化方式,每一個快個幾百毫秒,一個大項目,幾萬行代碼下了

 

就快了多少這樣,特別是大數據,幾億數據遍歷那樣快了不知道多了都,

一個代碼塊實現有不少種方法,多測試,看看哪一種速度最快,測試多了,積累經驗,就能寫出高效的代碼

1.PHP性能優化工具篇Benchmark類調試執行時間

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代碼優化部分

2.第二講講義

 

第一章:程序優化部分(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框架,框架自己都會消耗必定的資源。

3、      緩存優化

3.        緩存例子

文件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讀取文件效率最高

4.        第三講講義

 

 

相對來講,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');

 

 

4、      數據庫優化

查詢,高效的sql語句

索引/建表

服務器方面/主從複製

 

 

 

優化1查詢一條數據 時加limit 1。

 

5.        第四講講義

 

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列中索引的位圖,而且是冗餘的。

 

 

5、      nginx優化

配置方面

服務器緩存

6、      集羣及綜合優化

lvs負載均衡

web服務器集羣,數據庫讀寫分離,分表分庫,緩存服務器,所有集體搭建配合工做

集羣假設(負載均衡+緩存服務器+集羣服務器+數據庫服務器+keeplive心跳線)

加速cdn 消息隊列排隊原理

7、      Linux

cpu調優

內存的調優

相關文章
相關標籤/搜索