1. 程式人生 > >MySQL之索引原理

MySQL之索引原理

  一、索引原理

  1,什麼是索引?

  索引在MySQL中也叫‘鍵’或者‘key’,是儲存引擎用於快速找到記錄的一種資料結構。索引對於良好的效能非常關鍵,尤其是當表中的資料量越來越大時,索引對於效能的影響愈發重要,減少IO次數,加快查詢。

  2,索引的資料結構:b+樹

  上圖就是一個b+樹的資料結構,我們的InnoDB索引的資料就是以這種結構存放的。比如說我們要查詢29,首先會把磁碟塊1載入到記憶體,發生一次IO,發現29在17和35 中間,就鎖定磁碟塊中的p2指向的磁碟模組3,然後把磁碟塊3載入到記憶體,發生第二次IO,發現29在26和30之間,就鎖定磁碟塊3中p2指向的磁碟塊8,然後把磁碟塊8載入到記憶體,發生第三次IO,此時和29相比,有一值等於29,從而就找到了29。這樣的b+樹可以表示上百萬的資料,如果上百萬的資料查詢也只需要三次IO,那麼效能提高是非常大的,如果沒有索引,每次資料項都要發生一次IO,總共需要上百萬次的IO,得花多少時間。

  3,b+樹的性質

  3.1 索引欄位要儘量的小

  通過上面的例子來看,基本上是b+樹的層級高度決定了IO的次數,也決定了查詢的效率,所以,要提高效率就應該減少b+樹的高度。對於每個磁碟塊所能存放的資料量是有限的。假設當前的所有資料大小為N,每個磁碟能存放某個資料的個數為m=磁碟塊的大小/每個資料的大小,則高度為h=log(m+1)N,當資料一定時,m越大,h就越小。說明每個資料越小,高度越低,IO次數就越少,效率就更高。所以我們在建立索引的時候喜歡用id欄位,而不是name欄位,數字型別肯定比char型別佔的空間小嘛。

  3.2 索引的最左匹配原則特性

  查詢資料是從資料塊的左邊開始匹配,再匹配右邊的。

  二、聚集索引與輔助索引

  資料庫中的b+樹索引可以分為聚集索引和輔助索引

  相同點:其內部都是b+樹的形式,葉子節點都存放著資料

  不同點:聚集索引存放的是一整行所有資料,而輔助索引只存放索引欄位的資料+主鍵

  1,聚集索引

#InnoDB儲存引擎表示索引組織表,即表中資料按照主鍵順序存放。而聚集索引(clustered index)就是按照每張表的主鍵構造一棵B+樹,同時葉子結點存放的即為整張表的行記錄資料,也將聚集索引的葉子結點稱為資料頁。聚集索引的這個特性決定了索引組織表中資料也是索引的一部分。
同B+樹資料結構一樣,每個資料頁都通過一個雙向連結串列來進行連結。
#如果未定義主鍵,MySQL取第一個唯一索引(unique)而且只含非空列(NOT NULL)作為主鍵,InnoDB使用它作為聚簇索引。 #如果沒有這樣的列,InnoDB就自己產生一個這樣的ID值,它有六個位元組,而且是隱藏的,使其作為聚簇索引。 #由於實際的資料頁只能按照一棵B+樹進行排序,因此每張表只能擁有一個聚集索引。在多少情況下,查詢優化器傾向於採用聚集索引。因為聚集索引能夠在B+樹索引的葉子節點上直接找到資料。此外由於定義了資料的邏輯順序,聚集索引能夠特別快地訪問針對範圍值得查詢。

  它對主鍵的排序和範圍查詢熟讀非常的快,葉子節點的資料就是使用者所要查詢的資料,如使用者需要查詢一張表,查詢最後的10位使用者資訊,由於b+樹索引是雙向連結串列,所以使用者可以快速查詢到最後一個數據夜,並取出10條資料。

#參照第六小結測試索引的準備階段來創建出表s1
mysql> desc s1; #最開始沒有主鍵
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   |     | NULL    |       |
| name   | varchar(20) | YES  |     | NULL    |       |
| gender | char(6)     | YES  |     | NULL    |       |
| email  | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
rows in set (0.00 sec)

mysql> explain select * from s1 order by id desc limit 10; #Using filesort,需要二次排序
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+----------------+
|  1 | SIMPLE      | s1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 2633472 |   100.00 | Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+----------------+
row in set, 1 warning (0.11 sec)

mysql> alter table s1 add primary key(id); #新增主鍵
Query OK, 0 rows affected (13.37 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select * from s1 order by id desc limit 10; #基於主鍵的聚集索引在建立完畢後就已經完成了排序,無需二次排序
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------+
|  1 | SIMPLE      | s1    | NULL       | index | NULL          | PRIMARY | 4       | NULL |   10 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------+
row in set, 1 warning (0.04 sec)
View Code

  範圍查詢,即如果查詢主鍵某一範圍內的資料,通過葉子節點的上層中間節點就可以得到頁的範圍,之後直接讀取資料既可。

mysql> alter table s1 drop primary key;
Query OK, 2699998 rows affected (24.23 sec)
Records: 2699998  Duplicates: 0  Warnings: 0

mysql> desc s1;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   |     | NULL    |       |
| name   | varchar(20) | YES  |     | NULL    |       |
| gender | char(6)     | YES  |     | NULL    |       |
| email  | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
rows in set (0.12 sec)

mysql> explain select * from s1 where id > 1 and id < 1000000; #沒有聚集索引,預估需要檢索的rows數如下,explain就是預估一下你的sql的執行效率
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | s1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 2690100 |    11.11 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------------+
row in set, 1 warning (0.00 sec)

mysql> alter table s1 add primary key(id);
Query OK, 0 rows affected (16.25 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select * from s1 where id > 1 and id < 1000000; #有聚集索引,預估需要檢索的rows數如下
+----+-------------+-------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | s1    | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL | 1343355 |   100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
row in set, 1 warning (0.09 sec)
View Code

  2,輔助索引

  當我們把id作為主鍵,但我們查詢的時候,並不是以id為條件,而寫的是where name=‘dd’時,就沒法用到主鍵索引,此時查詢的效率就會很慢,從而我們就需要引入輔助索引,給name新增一個輔助索引。

  聚集索引的葉子節點上存放的是一整行的資料,但輔助索引就不是,它的葉子節點只存放了對應欄位的資料加上主鍵。如果我們用輔助索引拿到對應欄位的資料,如select name from t1 where name=‘kk’這種我們稱為覆蓋索引。如果通過輔助索引拿得不是對應欄位的資料,如select sex from t1 where name= ‘kk’,我們通過輔助索引是不能直接拿到sex,但我們可以通過輔助索引拿到對應的主鍵id,再通過聚集索引找到一整行資料,再從一整行資料中拿到sex值,種操作叫回表,

  三、MySQL索引管理

  1,功能

  索引的功能就是加快查詢,mysql中primary key,unique ,聯合唯一都是索引,這些索引除了加速查詢之外,還有約束的功能。

  2,MySQL常用的索引

普通索引INDEX:加速查詢

唯一索引:
    -主鍵索引PRIMARY KEY:加速查詢+約束(不為空、不能重複)
    -唯一索引UNIQUE:加速查詢+約束(不能重複)

聯合索引:
    -PRIMARY KEY(id,name):聯合主鍵索引
    -UNIQUE(id,name):聯合唯一索引
    -INDEX(id,name):聯合普通索引

  3,建立/刪除索引的語法

#方法一:建立表時
      CREATE TABLE 表名 (
                欄位名1  資料型別 [完整性約束條件…],
                欄位名2  資料型別 [完整性約束條件…],
                [UNIQUE | FULLTEXT | SPATIAL ]   INDEX | KEY
                [索引名]  (欄位名[(長度)]  [ASC |DESC]) 
                );


#方法二:CREATE在已存在的表上建立索引
        CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名 
                     ON 表名 (欄位名[(長度)]  [ASC |DESC]) ;


#方法三:ALTER TABLE在已存在的表上建立索引
        ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX
                             索引名 (欄位名[(長度)]  [ASC |DESC]) ;
                             
#刪除索引:DROP INDEX 索引名 ON 表名字;

  示範程式碼

#方式一
create table t1(
    id int,
    name char,
    age int,
    sex enum('male','female'),
    unique key uni_id(id),
    index ix_name(name) #index沒有key
);


#方式二
create index ix_age on t1(age);

#方式三
alter table t1 add index ix_sex(sex);

#檢視
mysql> show create table t1;
| t1    | CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` char(1) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` enum('male','female') DEFAULT NULL,
  UNIQUE KEY `uni_id` (`id`),
  KEY `ix_name` (`name`),
  KEY `ix_age` (`age`),
  KEY `ix_sex` (`sex`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

  四、正確使用索引

  首先,我們得有一個認識,建立索引確實可以幫助我們加速查詢,而且可以建立輔助索引,但並不是說我們把每個欄位都給加上輔助索引然後就會很方便,其實在索引存在很多的時候,會讓應用程式的效能受到影響,在建立多少索引這問題上,應該找到一個平衡點。

  其次,在我們添加了索引以後並不是一定查詢速度就很快,這和我們如何去查詢有關,比如下面幾種情況:

  1,範圍問題、或者條件不明確,條件中出現這些符號或關鍵字:>,<,>=,<=,!=,between  and 

  出現上面的情況相當於不是精確查詢,而是給的一個範圍或者是模糊查詢,這導致查詢的時候還得去一一進行比較,所以效率也不高,當我們查詢的範圍越大時,肯定是越慢的,當查詢範圍越小時,肯定是越快的

  2,like

  當查詢條件中出現like時,若沒有%,_符號時,如‘xx’就是精確查詢,速度很快的;當有符號時,當符號在前時,如‘%xx’,根據最左匹配原則,肯定先匹配%,由於%代表任意字元,所以會導致把所有的資料都要匹配一下,這效率沒有提高;但當符號在後就不一樣了,如‘xx%’,根據最左匹配原則,先匹配上xx,此時就可以把很多給直接排除,導致速度也很快。

  3,儘量選擇區分度高的欄位作為索引,比如我們選擇性別作為索引,不是男的就是女的,在查詢的時候回得到很多資料,這樣也會很慢,而且沒有實際意義

我們編寫儲存過程為表s1批量新增記錄,name欄位的值均為egon,也就是說name這個欄位的區分度很低(gender欄位也是一樣的,我們稍後再搭理它)

回憶b+樹的結構,查詢的速度與樹的高度成反比,要想將樹的高低控制的很低,需要保證:在某一層內資料項均是按照從左到右,從小到大的順序依次排開,即左1<左2<左3<...

而對於區分度低的欄位,無法找到大小關係,因為值都是相等的,毫無疑問,還想要用b+樹存放這些等值的資料,只能增加樹的高度,欄位的區分度越低,則樹的高度越高。極端的情況,索引欄位的值都一樣,那麼b+樹幾乎成了一根棍。本例中就是這種極端的情況,
name欄位所有的值均為'egon' #現在我們得出一個結論:為區分度低的欄位建立索引,索引樹的高度會很高,然而這具體會帶來什麼影響呢??? #1:如果條件是name='xxxx',那麼肯定是可以第一時間判斷出'xxxx'是不在索引樹中的(因為樹中所有的值均為'egon’,看第一條的時候就知道你不在索引樹裡面了),所以查詢速度很快 #2:如果條件正好是name='egon',查詢時,我們永遠無法從樹的某個位置得到一個明確的範圍,只能往下找,往下找,往下找。。。這與全表掃描的IO次數沒有多大區別,所以速度很慢

  4,索引最好不要參與計算,比如把條件寫成where id*3=3000,這樣相當於每次都要把id拿來計算一下才比,把所有資料都過一遍,很慢的,但我們寫成where id = 3000/3,條件是一樣的,但銷量就高很多

  5,and,or

#1、and與or的邏輯
    條件1 and 條件2:所有條件都成立才算成立,但凡要有一個條件不成立則最終結果不成立
    條件1 or 條件2:只要有一個條件成立則最終結果就成立

#2、and的工作原理
    條件:
        a = 10 and b = 'xxx' and c > 3 and d =4
    索引:
        製作聯合索引(d,a,b,c)
    工作原理:  #如果是你找的話,你會怎麼找,是不是從左到右一個一個的比較啊,首先你不能確定a這個欄位是不是有索引,即便是有索引,也不一定能確保命中索引了(所謂命中索引,就是應用上了索引),mysql不會這麼笨的,看下面mysql是怎麼找的:
        索引的本質原理就是先不斷的把查詢範圍縮小下來,然後再進行處理,對於連續多個and:mysql會按照聯合索引,從左到右的順序找一個區分度高的索引欄位(這樣便可以快速鎖定很小的範圍),加速查詢,即按照d—>a->b->c的順序

#3、or的工作原理
    條件:
        a = 10 or b = 'xxx' or c > 3 or d =4
    索引:
        製作聯合索引(d,a,b,c)
        
    工作原理:
        只要一個匹配成功就行,所以對於連續多個or:mysql會按照條件的順序,從左到右依次判斷,即a->b->c->d

  五、聯合索引與覆蓋索引

  1,聯合索引

  聯合索引就是把表的多個欄位合起來作為一個索引。

mysql> create table t(
    -> a int,
    -> b int,
    -> primary key(a),
    -> key idx_a_b(a,b)
    -> );
Query OK, 0 rows affected (0.11 sec)

  上圖就是一個聯合索引的資料結構圖,是按照(a,b)的順序進行了存放。

  select * from t1 where a=2 and b=1;這是可以使用聯合索引加速查詢的

  select * from t1 where a=3;這也可以用聯合索引加速查詢的,可以看出是按a排序的

  但是,select * from t1 where b=2;這是不能使用聯合索引加速查詢的,因為不是按b排序,從上到下,從左到右,b的值都是亂的

  注意:建立聯合索引時,把區分度高的放在前面,即最左邊,依次排下去,範圍查詢放在後面

  聯合索引第二好處:第一個欄位的值相同時,就已經對第二個欄位的值進行了排序,上圖中的a為1時,b的值從左往右增大的,排好序了的

create table buy_log(
    userid int unsigned not null,
    buy_date date
);

insert into buy_log values
(1,'2009-01-01'),
(2,'2009-01-01'),
(3,'2009-01-01'),
(1,'2009-02-01'),
(3,'2009-02-01'),
(1,'2009-03-01'),
(1,'2009-04-01');

alter table buy_log add key(userid);
alter table buy_log add key(userid,buy_date);

#===========驗證==============
mysql> show create table buy_log;
| buy_log | CREATE TABLE `buy_log` (
  `userid` int(10) unsigned NOT NULL,
  `buy_date` date DEFAULT NULL,
  KEY `userid` (`userid`),
  KEY `userid_2` (`userid`,`buy_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

#可以看到possible_keys在這裡有兩個索引可以用,分別是單個索引userid與聯合索引userid_2,但是優化器最終選擇了使用的key是userid因為該索引的葉子節點包含單個鍵值,所以理論上一個頁能存放的記錄應該更多
mysql> explain select * from buy_log where userid=2;
+----+-------------+---------+------+-----------------+--------+---------+-------+------+-------+
| id | select_type | table   | type | possible_keys   | key    | key_len | ref   | rows | Extra |
+----+-------------+---------+------+-----------------+--------+---------+-------+------+-------+
|  1 | SIMPLE      | buy_log | ref  | userid,userid_2 | userid | 4       | const |    1 |       |
+----+-------------+---------+------+-----------------+--------+---------+-------+------+-------+
row in set (0.00 sec)

#接著假定要取出userid為1的最近3次的購買記錄,用的就是聯合索引userid_2了,因為在這個索引中,在userid=1的情況下,buy_date都已經排序好了
mysql> explain select * from buy_log where userid=1 order by buy_date desc limit 3;
+----+-------------+---------+------+-----------------+----------+---------+-------+------+--------------------------+
| id | select_type | table   | type | possible_keys   | key      | key_len | ref   | rows | Extra                    |
+----+-------------+---------+------+-----------------+----------+---------+-------+------+--------------------------+
|  1 | SIMPLE      | buy_log | ref  | userid,userid_2 | userid_2 | 4       | const |    4 | Using where; Using index |
+----+-------------+---------+------+-----------------+----------+---------+-------+------+--------------------------+
row in set (0.00 sec)

#ps:如果extra的排序顯示是Using filesort,則意味著在查出資料後需要二次排序(如下查詢語句,沒有先用where userid=3先定位範圍,於是即便命中索引也沒用,需要二次排序)
mysql> explain select * from buy_log order by buy_date desc limit 3;
+----+-------------+---------+-------+---------------+----------+---------+------+------+-----------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows | Extra                       |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | buy_log | index | NULL          | userid_2 | 8       | NULL |    7 | Using index; Using filesort |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-----------------------------+


#對於聯合索引(a,b),下述語句可以直接使用該索引,無需二次排序
select ... from table where a=xxx order by b;

#然後對於聯合索引(a,b,c)來首,下列語句同樣可以直接通過索引得到結果
select ... from table where a=xxx order by b;
select ... from table where a=xxx and b=xxx order by c;

#但是對於聯合索引(a,b,c),下列語句不能通過索引直接得到結果,還需要自己執行一次filesort操作,因為索引(a,c)並未排序
select ... from table where a=xxx order by c;
View Code

  2,覆蓋索引

  上面講了,利用輔助索引拿到輔助索引對應欄位的值,不需要從聚集索引中拿整行資料的操作叫覆蓋索引。輔助索引不包含整行資料,其大小遠小於聚集索引,因此減少大量的IO操作。

  2.1對於統計問題而言,相較於聚集索引,還是會選擇輔助索引,這是優化器的操作結果

mysql> explain select count(*) from buy_log;
+----+-------------+---------+-------+---------------+--------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key    | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+--------+---------+------+------+-------------+
|  1 | SIMPLE      | buy_log | index | NULL          | userid | 4       | NULL |    7 | Using index |
+----+-------------+---------+-------+---------------+--------+---------+------+------+-------------+
row in set (0.00 sec)

  2.2對於(a,b)形式的聯合索引,一般不可以選擇b的查詢條件,相當於說查詢條件中沒有a,只有b時是用不到聯合索引的,但是做統計操作時,優化器還是會選擇聯合索引的

#聯合索引userid_2(userid,buy_date),一般情況,我們按照buy_date是無法使用該索引的,但特殊情況下:查詢語句是統計操作,且是覆蓋索引,則按照buy_date當做查詢條件時,也可以使用該聯合索引
mysql> explain select count(*) from buy_log where buy_date >= '2011-01-01' and buy_date < '2011-02-01';
+----+-------------+---------+-------+---------------+----------+---------+------+------+--------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows | Extra                    |
+----+-------------+---------+-------+---------------+----------+---------+------+------+--------------------------+
|  1 | SIMPLE      | buy_log | index | NULL          | userid_2 | 8       | NULL |    7 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+------+--------------------------+
row in set (0.00 sec)

  六、查詢優化器-explain

  優化器中,key表示採用的索引是哪一個,rows是核心指標,表示查詢過程總共需要檢視幾條資料,當rows很小的語句執行一定很快的,所以優化語句基本上都是在優化rows。

  使用方法:在select語句前加上explain就行了

  具體檢視http://www.cnblogs.com/yycc/p/7338894.html,關於優化器的詳細講解

  七、查詢優化的基本步驟

0.先執行看看是否真的很慢,注意設定SQL_NO_CACHE
1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單表每個欄位分別查詢,看哪個欄位的區分度最高
2.explain檢視執行計劃,是否與1預期一致(從鎖定記錄較少的表開始查詢)
3.order by limit 形式的sql語句讓排序的表優先查
4.瞭解業務方使用場景
5.加索引時參照建索引的幾大原則
6.觀察結果,不符合預期繼續從0分析

  八、慢日誌管理

慢日誌
            - 執行時間 > 10
            - 未命中索引
            - 日誌檔案路徑
            
        配置:
            - 記憶體
                show variables like '%query%';
                show variables like '%queries%';
                set global 變數名 =- 配置檔案
                mysqld --defaults-file='E:\wupeiqi\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-default.ini'
                
                my.conf內容:
                    slow_query_log = ON
                    slow_query_log_file = D:/....
                    
                注意:修改配置檔案之後,需要重啟服務
View Code
MySQL日誌管理
========================================================
錯誤日誌: 記錄 MySQL 伺服器啟動、關閉及執行錯誤等資訊
二進位制日誌: 又稱binlog日誌,以二進位制檔案的方式記錄資料庫中除 SELECT 以外的操作
查詢日誌: 記錄查詢的資訊
慢查詢日誌: 記錄執行時間超過指定時間的操作
中繼日誌: 備庫將主庫的二進位制日誌複製到自己的中繼日誌中,從而在本地進行重放
通用日誌: 審計哪個賬號、在哪個時段、做了哪些事件
事務日誌或稱redo日誌: 記錄Innodb事務相關的如事務執行時間、檢查點等
========================================================
一、bin-log
1. 啟用
# vim /etc/my.cnf
[mysqld]
log-bin[=dir\[filename]]
# service mysqld restart
2. 暫停
//僅當前會話
SET SQL_LOG_BIN=0;
SET SQL_LOG_BIN=1;
3. 檢視
檢視全部:
# mysqlbinlog mysql.000002
按時間:
# mysqlbinlog mysql.000002 --start-datetime="2012-12-05 10:02:56"
# mysqlbinlog mysql.000002 --stop-datetime="2012-12-05 11:02:54"
# mysqlbinlog mysql.000002 --start-datetime="2012-12-05 10:02:56" --stop-datetime="2012-12-05 11:02:54" 

按位元組數:
# mysqlbinlog mysql.000002 --start-position=260
# mysqlbinlog mysql.000002 --stop-position=260
# mysqlbinlog mysql.000002 --start-position=260 --stop-position=930
4. 截斷bin-log(產生新的bin-log檔案)
a. 重啟mysql伺服器
b. # mysql -uroot -p123 -e 'flush logs'
5. 刪除bin-log檔案
# mysql -uroot -p123 -e 'reset master' 


二、查詢日誌
啟用通用查詢日誌
# vim /etc/my.cnf
[mysqld]
log[=dir\[filename]]
# service mysqld restart

三、慢查詢日誌
啟用慢查詢日誌
# vim /etc/my.cnf
[mysqld]
log-slow-queries[=dir\[filename]]
long_query_time=n
# service mysqld restart
MySQL 5.6:
slow-query-log=1
slow-query-log-file=slow.log
long_query_time=3
檢視慢查詢日誌
測試:BENCHMARK(count,expr)
SELECT BENCHMARK(50000000,2*3);
View Code