注意:在使用模糊查詢的時候,當% 在第一個字母的位置的時候,這個時候索引是沒法被使用的。可是% 在其餘的位置的時候,索引是能夠被使用的。 php
# select * from tableName where name like "%zhangsan"; ?可使用到索引啊? 不能夠。 mysql
分析:由於是不肯定查詢,在表中任何一行記錄都有可能知足查詢條件。 sql
#select * from tableName where name like "zh%"; 可使用嗎? 能夠 數組
#select * from tableName where name like "zh%三"; 可使用嗎? 能夠 緩存
# select * from tableName where name like "z%san"; ? 可使用嗎?能夠,首先能夠快速定位z字母開頭的部分。讀z字母這段範圍以內只能逐行比較。 服務器
# select * from tableName where id+1 = 1000; 架構
# select * from tableName where id = 999; 等價。 函數
有的時候,會在查詢字段上面使用函數。使用函數的時候也是沒法使用全部的,通常的解決方案是將查詢後的結果交給php程序(字符串 和 數組)來實現處理。不要把函數的處理放在MySQL裏面完成。 工具
答: 測試
執行order by 不加限定,全表掃描,filesort含義 注意:問題?
答:
解釋:MySQL的客戶端在發送sql語句到MySQL服務器端以後,會先去檢查一下權限,以後去查詢該條sql語句的緩存信息是否存在,若是存在,則直接返回;若是不存在,MySQL服務器須要去分析該sql語句,作詞法語法分析,而後編譯,生產執行樹,去磁盤上獲取數據,獲取數據後,緩存到自身的一個緩存容器裏面,而後在返回數據。
使用:
# show variables like "%cache%";
更改MySQL緩存的大小(32M),注意 單位是 B(字節)
# set global query_cache_size = 1024*1024*32;
注意:第一個是要加關鍵字 global 第二個是大小的單位爲 B(字節) 第三具體給多少合適,取決於自身操做系統的內存大小。
測試對比:
注意:MySQL自身的緩存須要注意兩點:
分析:
因爲一個網站業務中 70%的業務基本都是讀操做,剩下的都是寫操做。因此這個時候對讀的壓力過大,須要使用必定的方式來減小壓力,這個時候可使用讀寫分離這種架構來實現壓力的分擔。
怎麼查詢是讀爲主?
# show status like "%Com_%";
經過上面的分析一段時間,就能夠大體計算出網站的讀寫狀況
# show status ; 能夠查看MySQL的一個狀態信息。
讀寫分離概圖:
mysql-proxy這個工具能夠實現對sql語句的分析,判斷sql語句是讀操做(select關鍵字) 仍是 寫操做(insert、update、delete)。最後去鏈接不一樣的服務器實現業務的完成。
當完成讀的時候,MySQL-proxy會從對臺讀服務器按照必定策略去選擇一臺(輪詢、加權、ip_hash)完成讀操做
當完成寫的時候,直接去鏈接寫的服務器
問題:
因爲數據只在主服務器上實現寫操做,可是從服務器上是沒有完成寫操做的,這個時候數據就會不一致。
須要解決一致性的問題?
答:可使用MySQL的一個bin日誌來完成數據的一致性問題。
使用步驟:
主服務器配置:
從服務器配置:
總結:主從複製是完成讀寫分離的一個基礎。(稍微有點延時)
對於MyISAM的存儲引擎來講,若是查詢的字段信息正好在索引文件裏面出現,這個時候不須要作回行的操做,直接能夠從索引文件裏面返回的現象就叫作索引覆蓋。(索引正好覆蓋了查詢的字段)
應用:在大數據(百萬數據)下的一個翻頁效果
技術點:翻頁是如何作的?
答:select * from tableName limit offset,page;
比如如今是N頁,每頁顯示page條
offset = (N-1) * page
實際使用:
分頁操做
當很大頁碼的時候
經過上面的對比發現,MySQL在使用limit分頁的時候,在頁碼足夠大的狀況下,效率是很低的,爲何?
答:主要緣由是,MySQL在使用limit作查詢的時候,以下sql:
select * from tableName limit offset,page;
執行過程:
先取出 offset+page 條記錄, 而後在丟棄 offset 條記錄 ,返回 page 條記錄。
因此有必要對這種狀況作優化操做:
百度限制用戶行爲:
當分頁頁碼變大的狀況下:
經過使用 where id > Number limit 10; 這樣因爲可使用上id的主鍵索引,因此能夠快速的定位,達到一個大數據的分頁的效果。
問題:
a. select * from tableName where id > Number limit page;
b. select * from tableName limit Number, page;
當上面的這兩條sql語句執行後,結果在何時徹底一致,何時不一致?
答:當數據沒有被物理行刪除的時候。這個時候數據是一致的,可是有物理行刪除的時候,數據是不一致的。
如何解決上面的問題?
答:既然是物理行刪除形成的,那就不作物理行的刪除,只作邏輯刪除(設置一個is_delete 字段 0 表明沒有刪除 1 表明已經刪除)。
使用邏輯刪除以後,數據會一致,只要在數據顯示的,在顯示層面(HTML)讓is_delete=1 不顯示出來便可。if( is_delete == 1) echo '該條信息已被刪除!' 例如:常見的百度貼吧,網易新聞端。
3. 實現物理行刪除,不限制用戶行爲
答:這個時候可使用 索引覆蓋 + 延時關聯技巧 來實現。
分析:
程序代碼實現:
在php層面實現
foreach($data as $k=>$v){
$sql = select * from tableName where id = $v;
$res = mysql_query($sql);
$row = mysql_fetch_assoc($res);
$result[]= $row;
}
$result //分頁數據
在MySQL層面聯表處理:
使用聯表來完成大數據的分頁操做
解釋