數據庫優化

目的:1.避免慢查詢形成頁面沒法加載mysql

           2.因爲數據庫鏈接timeout產生5xx錯誤sql

           3.因爲阻塞形成數據沒法提交數據庫

慢查詢分析日誌:pt-query-digest分析前幾個查詢函數

優化當面入手:優化

硬件,系統配置,數據庫表結構,sql及索引   效果:低到高  成本: 高到低操作系統

rpm -qal | grep mysql  查找mysql字段目錄線程

ps -ef | grep mysql  查看線程號和目錄unix

cat /etc/my.conf  mysql配置文件日誌

 

datadir是你數據文件的存放路徑排序

basedir纔是mysql軟件的安裝路徑

explain      --查詢sql執行技術

 

key_len:使用的索引的長度,在不損失精確度狀況下,長度越短越好

ref:顯示索引的哪一列被使用,若是可能的話,是一個常數最好

type 顯示鏈接使用什麼類型,從好到差:const,eq_reg,ref,range,index,all

         extra列須要注意的返回值

                Using filesort: 查詢須要優化,須要額外的步驟來發現如何對返回的行排序,使用文件排序

                Using temporary:   查詢須要優化 ,這裏建立臨時表進行存儲結構,一般發生在不一樣列集上的order by,而不是group by

備份

           mysqldump --all-databases > all-databases.sql(將全部數據庫備份到all-databases.sql文件,all-databases.sql是一個文本文件,文件名任取。)

count()和max()優化:

        count(*)查詢行數

        count(1)查詢不爲null的行數

        max(age)->age字段創建索引 count()同理

子查詢優化:

        改成鏈接join查詢(注意1對多關係)

group by優化方式:

         在子查詢用group by過濾條件  

         例如:

 

優化前:explain select a.name,c.cnt from a inner join b  using id group by b.id;

 

優化後:explain select a.name,c.cnt from a inner join(select id,count(*) from b group by id)  as c using id;

 

limit優化方式:

        limit經常使用分頁處理,時常會伴隨order by 從句使用,所以常常會形成filesort這樣的I/O問題

        步驟1:使用索引的列或者主鍵進行order by操做

        步驟2:藉助上一次返回的id,用id進行過濾,缺點:id自增且連續   --->避免數量亮大時掃描過多的記錄

                   例如:select id from a where id >55 and id<=60 order by id limit 1,5;

如何選擇合適的列創建索引?

        1.在where,group by ,order by,on 從句中出現的列

        2.索引字段越小越好

        3.離散度大的列放在聯合索引前面

          例如:select * from payment where staff_id =2 and customer_id =584;

          因爲customer_id離散度更大,因此應該是(customer_id,staff_id);

          如何判斷列的離散度大小    ---> select count(distinct customer_id) from payment;   -->599

                                                             select count(distinct staff_id) from payment; -->2

索引優化   

         過多的索引會影響寫入,有時也會影響查詢

         冗餘索引:多個索引的前綴列相同,或在聯合索引中包含了主鍵的索引,下面key(name,id)就是一個冗餘索引

                           create table test(

                           id int not null primay key,

                           name varchar(10) not null,

                           title varchar(50) not null,

                           key(name,id)

                           )engine=innodb

         重複索引:相同的列以相同的順序創建的同類型的索引。下面primary key和id列上的索引就是重複索引                    

                            create table test(

                           id int not null primay key,

                           name varchar(10) not null,

                           title varchar(50) not null,

                           unique(id)

                           )engine=innodb

        使用pt-duplicate-key-checker  -uroot -p'' -h127.0.0.1檢查重複索引和冗餘索引

選擇的合適的數據類型

       1.使用能夠存下你的數據的最小數據類型

       2.使用簡單的數據類型,int要比varchar類型在mysql處理上簡單

       3.儘量使用not null定義字段

       4.儘可能少用text類型,非用不可時最好考慮分表

       使用int來存儲日期時間,利用from_unixtime(),unix_timestamp()2個函數來進行轉換

       使用bigint來存ip地址,使用inet_aton(),inet_ntoa()2個函數來替換

表的垂直拆分,水平拆分

       垂直拆分:將單表按照業務拆分多個表

       水平拆分:單表分紅多個相同的表,表1,表2,表3。。。。。

操做系統配置優化

相關文章
相關標籤/搜索