1. 程式人生 > >資料庫索引實現原理以及SQL優化技巧

資料庫索引實現原理以及SQL優化技巧

mysql資料庫的索引的實現方式(

B-Tree和B+Tree  這裡以mysql資料庫為例)

關於B樹和B+樹請參考關於B樹的一些總結,這篇文章介紹的比較詳細,同時容易理解。

目前大部分資料庫系統及檔案系統都採用B-Tree或其變種B+Tree作為索引結構,在本文的下一節會結合儲存器原理及計算機存取原理討論為什麼B-Tree和B+Tree在被如此廣泛用於索引,這一節先單純從資料結構角度描述它們。

B-Tree

為了描述B-Tree,首先定義一條資料記錄為一個二元組[key, data],key為記錄的鍵值,對於不同資料記錄,key是互不相同的;data為資料記錄除key外的資料。那麼B-Tree是滿足下列條件的資料結構:

  1. d>=2,即B-Tree的度;
  2. h為B-Tree的高;
  3. 每個非葉子結點由n-1個key和n個指標組成,其中d<=n<=2d;
  4. 每個葉子結點至少包含一個key和兩個指標,最多包含2d-1個key和2d個指標,葉結點的指標均為NULL;
  5. 所有葉結點都在同一層,深度等於樹高h;
  6. key和指標相互間隔,結點兩端是指標;
  7. 一個結點中的key從左至右非遞減排列;
  8. 如果某個指標在結點node最左邊且不為null,則其指向結點的所有key小於v(key1),其中v(key1)為node的第一個key的值。
  9. 如果某個指標在結點node最右邊且不為null,則其指向結點的所有key大於v(keym),其中v(keym)為node的最後一個key的值。
  10. 如果某個指標在結點node的左右相鄰key分別是keyi和keyi+1且不為null,則其指向結點的所有key小於v(keyi+1)且大於v(keyi)。

圖2是一個d=2的B-Tree示意圖。

圖2

由於B-Tree的特性,在B-Tree中按key檢索資料的演算法非常直觀:首先從根節點進行二分查詢,如果找到則返回對應節點的data,否則對相應區間的指標指向的節點遞迴進行查詢,直到找到節點或找到null指標,前者查詢成功,後者查詢失敗。B-Tree上查詢演算法的虛擬碼如下:

複製程式碼
BTree_Search(node, key) {
    if(node == null) return null
; foreach(node.key) { if(node.key[i] == key) return node.data[i]; if(node.key[i] > key) return BTree_Search(point[i]->node); } return BTree_Search(point[i+1]->node); } data = BTree_Search(root, my_key);
複製程式碼

關於B-Tree有一系列有趣的性質,例如一個度為d的B-Tree,設其索引N個key,則其樹高h的上限為logd((N+1)/2),檢索一個key,其查詢結點個數的漸進複雜度為O(logdN)。從這點可以看出,B-Tree是一個非常有效率的索引資料結構。

B+Tree

B-Tree有許多變種,其中最常見的是B+Tree,例如MySQL就普遍使用B+Tree實現其索引結構。

與B-Tree相比,B+Tree有以下不同點:

  1. 每個結點的指標上限為2d而不是2d+1。
  2. 內結點不儲存data,只儲存key;葉子結點不儲存指標。

圖3是一個簡單的B+Tree示意。

圖3

由於並不是所有節點都具有相同的域,因此B+Tree中葉結點和內結點一般大小不同。這點與B-Tree不同,雖然B-Tree中不同節點存放的key和指標可能數量不一致,但是每個結點的域和上限是一致的,所以在實現中B-Tree往往對每個結點申請同等大小的空間。

一般來說,B+Tree比B-Tree更適合實現外儲存索引結構,具體原因與外儲存器原理及計算機存取原理有關,將在下面討論。

帶有順序訪問指標的B+Tree

一般在資料庫系統或檔案系統中使用的B+Tree結構都在經典B+Tree的基礎上進行了優化,增加了順序訪問指標。

圖4

如圖4所示,在B+Tree的每個葉子結點增加一個指向相鄰葉子結點的指標,就形成了帶有順序訪問指標的B+Tree。做這個優化的目的是為了提高區間訪問的效能,例如圖4中如果要查詢key為從18到49的所有資料記錄,當找到18後,只需順著結點和指標順序遍歷就可以一次性訪問到所有資料結點,極大提到了區間查詢效率。

這一節對B-Tree和B+Tree進行了一個簡單的介紹,下一節結合儲存器存取原理介紹為什麼目前B+Tree是資料庫系統實現索引的首選資料結構。

為什麼使用B-Tree(B+Tree)

上文說過,紅黑樹等資料結構也可以用來實現索引,但是檔案系統及資料庫系統普遍採用B-/+Tree作為索引結構,這一節將結合計算機組成原理相關知識討論B-/+Tree作為索引的理論基礎。

一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟I/O消耗,相對於記憶體存取,I/O存取的消耗要高几個數量級,所以評價一個數據結構作為索引的優劣最重要的指標就是在查詢過程中磁碟I/O操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟I/O的存取次數。下面先介紹記憶體和磁碟存取原理,然後再結合這些原理分析B-/+Tree作為索引的效率。

B-Tree和B+Tree

關於B樹和B+樹請參考關於B樹的一些總結,這篇文章介紹的比較詳細,同時容易理解。

目前大部分資料庫系統及檔案系統都採用B-Tree或其變種B+Tree作為索引結構,在本文的下一節會結合儲存器原理及計算機存取原理討論為什麼B-Tree和B+Tree在被如此廣泛用於索引,這一節先單純從資料結構角度描述它們。

B-Tree

為了描述B-Tree,首先定義一條資料記錄為一個二元組[key, data],key為記錄的鍵值,對於不同資料記錄,key是互不相同的;data為資料記錄除key外的資料。那麼B-Tree是滿足下列條件的資料結構:

  1. d>=2,即B-Tree的度;
  2. h為B-Tree的高;
  3. 每個非葉子結點由n-1個key和n個指標組成,其中d<=n<=2d;
  4. 每個葉子結點至少包含一個key和兩個指標,最多包含2d-1個key和2d個指標,葉結點的指標均為NULL;
  5. 所有葉結點都在同一層,深度等於樹高h;
  6. key和指標相互間隔,結點兩端是指標;
  7. 一個結點中的key從左至右非遞減排列;
  8. 如果某個指標在結點node最左邊且不為null,則其指向結點的所有key小於v(key1),其中v(key1)為node的第一個key的值。
  9. 如果某個指標在結點node最右邊且不為null,則其指向結點的所有key大於v(keym),其中v(keym)為node的最後一個key的值。
  10. 如果某個指標在結點node的左右相鄰key分別是keyi和keyi+1且不為null,則其指向結點的所有key小於v(keyi+1)且大於v(keyi)。

圖2是一個d=2的B-Tree示意圖。

圖2

由於B-Tree的特性,在B-Tree中按key檢索資料的演算法非常直觀:首先從根節點進行二分查詢,如果找到則返回對應節點的data,否則對相應區間的指標指向的節點遞迴進行查詢,直到找到節點或找到null指標,前者查詢成功,後者查詢失敗。B-Tree上查詢演算法的虛擬碼如下:

複製程式碼
BTree_Search(node, key) {
    if(node == null) return null;
    foreach(node.key)
    {
        if(node.key[i] == key) return node.data[i];
            if(node.key[i] > key) return BTree_Search(point[i]->node);
    }
    return BTree_Search(point[i+1]->node);
}
data = BTree_Search(root, my_key);
複製程式碼

關於B-Tree有一系列有趣的性質,例如一個度為d的B-Tree,設其索引N個key,則其樹高h的上限為logd((N+1)/2),檢索一個key,其查詢結點個數的漸進複雜度為O(logdN)。從這點可以看出,B-Tree是一個非常有效率的索引資料結構。

B+Tree

B-Tree有許多變種,其中最常見的是B+Tree,例如MySQL就普遍使用B+Tree實現其索引結構。

與B-Tree相比,B+Tree有以下不同點:

  1. 每個結點的指標上限為2d而不是2d+1。
  2. 內結點不儲存data,只儲存key;葉子結點不儲存指標。

圖3是一個簡單的B+Tree示意。

圖3

由於並不是所有節點都具有相同的域,因此B+Tree中葉結點和內結點一般大小不同。這點與B-Tree不同,雖然B-Tree中不同節點存放的key和指標可能數量不一致,但是每個結點的域和上限是一致的,所以在實現中B-Tree往往對每個結點申請同等大小的空間。

一般來說,B+Tree比B-Tree更適合實現外儲存索引結構,具體原因與外儲存器原理及計算機存取原理有關,將在下面討論。

帶有順序訪問指標的B+Tree

一般在資料庫系統或檔案系統中使用的B+Tree結構都在經典B+Tree的基礎上進行了優化,增加了順序訪問指標。

圖4

如圖4所示,在B+Tree的每個葉子結點增加一個指向相鄰葉子結點的指標,就形成了帶有順序訪問指標的B+Tree。做這個優化的目的是為了提高區間訪問的效能,例如圖4中如果要查詢key為從18到49的所有資料記錄,當找到18後,只需順著結點和指標順序遍歷就可以一次性訪問到所有資料結點,極大提到了區間查詢效率。

這一節對B-Tree和B+Tree進行了一個簡單的介紹,下一節結合儲存器存取原理介紹為什麼目前B+Tree是資料庫系統實現索引的首選資料結構。

為什麼使用B-Tree(B+Tree)

上文說過,紅黑樹等資料結構也可以用來實現索引,但是檔案系統及資料庫系統普遍採用B-/+Tree作為索引結構,這一節將結合計算機組成原理相關知識討論B-/+Tree作為索引的理論基礎。

一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟I/O消耗,相對於記憶體存取,I/O存取的消耗要高几個數量級,所以評價一個數據結構作為索引的優劣最重要的指標就是在查詢過程中磁碟I/O操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟I/O的存取次數。

索引使用策略及優化

MySQL的優化主要分為結構優化(Scheme optimization)和查詢優化(Query optimization)。本章討論的高效能索引策略主要屬於結構優化範疇。本章的內容完全基於上文的理論基礎,實際上一旦理解了索引背後的機制,那麼選擇高效能的策略就變成了純粹的推理,並且可以理解這些策略背後的邏輯。

示例資料庫

為了討論索引策略,需要一個數據量不算小的資料庫作為示例。本文選用MySQL官方文件中提供的示例資料庫之一:employees。這個資料庫關係複雜度適中,且資料量較大。下圖是這個資料庫的E-R關係圖(引用自MySQL官方手冊):

圖12

最左字首原理與相關優化

高效使用索引的首要條件是知道什麼樣的查詢會使用到索引,這個問題和B+Tree中的“最左字首原理”有關,下面通過例子說明最左字首原理。

這裡先說一下聯合索引的概念。在上文中,我們都是假設索引只引用了單個的列,實際上,MySQL中的索引可以以一定順序引用多個列,這種索引叫做聯合索引,一般的,一個聯合索引是一個有序元組<a1, a2, …, an>,其中各個元素均為資料表的一列,實際上要嚴格定義索引需要用到關係代數,但是這裡我不想討論太多關係代數的話題,因為那樣會顯得很枯燥,所以這裡就不再做嚴格定義。另外,單列索引可以看成聯合索引元素數為1的特例。

以employees.titles表為例,下面先檢視其上都有哪些索引:

複製程式碼
SHOW INDEX FROM employees.titles;
+--------+------------+----------+--------------+-------------+-----------+-------------+------+------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Null | Index_type |
+--------+------------+----------+--------------+-------------+-----------+-------------+------+------------+
| titles |          0 | PRIMARY  |            1 | emp_no      | A         |        NULL |      | BTREE      |
| titles |          0 | PRIMARY  |            2 | title       | A         |        NULL |      | BTREE      |
| titles |          0 | PRIMARY  |            3 | from_date   | A         |      443308 |      | BTREE      |
| titles |          1 | emp_no   |            1 | emp_no      | A         |      443308 |      | BTREE      |
+--------+------------+----------+--------------+-------------+-----------+-------------+------+------------+
複製程式碼

從結果中可以到titles表的主索引為<emp_no, title, from_date>,還有一個輔助索引<emp_no>。為了避免多個索引使事情變複雜(MySQL的SQL優化器在多索引時行為比較複雜),這裡我們將輔助索引drop掉:

ALTER TABLE employees.titles DROP INDEX emp_no;

這樣就可以專心分析索引PRIMARY的行為了。

全列匹配

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001' AND title='Senior Engineer' AND from_date='1986-06-26';
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref               | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+
|  1 | SIMPLE      | titles | const | PRIMARY       | PRIMARY | 59      | const,const,const |    1 |       |
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+

很明顯,當按照索引中所有列進行精確匹配(這裡精確匹配指“=”或“IN”匹配)時,索引可以被用到。這裡有一點需要注意,理論上索引對順序是敏感的,但是由於MySQL的查詢優化器會自動調整where子句的條件順序以使用適合的索引,例如我們將where中的條件順序顛倒:

EXPLAIN SELECT * FROM employees.titles WHERE from_date='1986-06-26' AND emp_no='10001' AND title='Senior Engineer';
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref               | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+
|  1 | SIMPLE      | titles | const | PRIMARY       | PRIMARY | 59      | const,const,const |    1 |       |
+----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+

效果是一樣的。

最左字首匹配

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001';
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table  | type | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | titles | ref  | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------+

當查詢條件精確匹配索引的左邊連續一個或幾個列時,如<emp_no>或<emp_no, title>,所以可以被用到,但是隻能用到一部分,即條件所組成的最左字首。上面的查詢從分析結果看用到了PRIMARY索引,但是key_len為4,說明只用到了索引的第一列字首。

查詢條件用到了索引中列的精確匹配,但是中間某個條件未提供

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001' AND from_date='1986-06-26';
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+
|  1 | SIMPLE      | titles | ref  | PRIMARY       | PRIMARY | 4       | const |    1 | Using where |
+----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+

此時索引使用情況和情況二相同,因為title未提供,所以查詢只用到了索引的第一列,而後面的from_date雖然也在索引中,但是由於title不存在而無法和左字首連線,因此需要對結果進行掃描過濾from_date(這裡由於emp_no唯一,所以不存在掃描)。如果想讓from_date也使用索引而不是where過濾,可以增加一個輔助索引<emp_no, from_date>,此時上面的查詢會使用這個索引。除此之外,還可以使用一種稱之為“隔離列”的優化方法,將emp_no與from_date之間的“坑”填上。

首先我們看下title一共有幾種不同的值:

複製程式碼
SELECT DISTINCT(title) FROM employees.titles;
+--------------------+
| title              |
+--------------------+
| Senior Engineer    |
| Staff              |
| Engineer           |
| Senior Staff       |
| Assistant Engineer |
| Technique Leader   |
| Manager            |
+--------------------+
複製程式碼

只有7種。在這種成為“坑”的列值比較少的情況下,可以考慮用“IN”來填補這個“坑”從而形成最左字首:

複製程式碼
EXPLAIN SELECT * FROM employees.titles
WHERE emp_no='10001'
AND title IN ('Senior Engineer', 'Staff', 'Engineer', 'Senior Staff', 'Assistant Engineer', 'Technique Leader', 'Manager')
AND from_date='1986-06-26';
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | titles | range | PRIMARY       | PRIMARY | 59      | NULL |    7 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
複製程式碼

這次key_len為59,說明索引被用全了,但是從type和rows看出IN實際上執行了一個range查詢,這裡檢查了7個key。看下兩種查詢的效能比較:

複製程式碼
SHOW PROFILES;
+----------+------------+-------------------------------------------------------------------------------+
| Query_ID | Duration   | Query                                                                         |
+----------+------------+-------------------------------------------------------------------------------+
|       10 | 0.00058000 | SELECT * FROM employees.titles WHERE emp_no='10001' AND from_date='1986-06-26'|
|       11 | 0.00052500 | SELECT * FROM employees.titles WHERE emp_no='10001' AND title IN ...          |
+----------+------------+-------------------------------------------------------------------------------+
複製程式碼

“填坑”後效能提升了一點。如果經過emp_no篩選後餘下很多資料,則後者效能優勢會更加明顯。當然,如果title的值很多,用填坑就不合適了,必須建立輔助索引。

查詢條件沒有指定索引第一列

EXPLAIN SELECT * FROM employees.titles WHERE from_date='1986-06-26';
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | titles | ALL  | NULL          | NULL | NULL    | NULL | 443308 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+

由於不是最左字首,索引這樣的查詢顯然用不到索引。

匹配某列字首字串

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001' AND title LIKE 'Senior%';
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | titles | range | PRIMARY       | PRIMARY | 56      | NULL |    1 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

此時可以用到索引,但是如果萬用字元不是隻出現在末尾,則無法使用索引。(原文表述有誤,如果萬用字元%不出現在開頭,則可以用到索引,但根據具體情況不同可能只會用其中一個字首)

範圍查詢

EXPLAIN SELECT * FROM employees.titles WHERE emp_no < '10010' and title='Senior Engineer';
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | titles | range | PRIMARY       | PRIMARY | 4       | NULL |   16 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

範圍列可以用到索引(必須是最左字首),但是範圍列後面的列無法用到索引。同時,索引最多用於一個範圍列,因此如果查詢條件中有兩個範圍列則無法全用到索引。

複製程式碼
EXPLAIN SELECT * FROM employees.titles
WHERE emp_no < '10010'
AND title='Senior Engineer'
AND from_date BETWEEN '1986-01-01' AND '1986-12-31';
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | titles | range | PRIMARY       | PRIMARY | 
            
           

相關推薦

資料庫索引實現原理以及SQL優化技巧

mysql資料庫的索引的實現方式( B-Tree和B+Tree  這裡以mysql資料庫為例) 關於B樹和B+樹請參考關於B樹的一些總結,這篇文章介紹的比較詳細,同時容易理解。 目前大部分資料庫系統及檔案系統都採用B-Tree或其變種B+Tree作為索引結構,在本文的

MySQL資料庫索引實現原理

前言:大家都知道資料庫的索引有著提升資料庫查詢速度的作用,但是很少有人對索引實現原理有深入探討,本文使用通俗語言進行解析,如有不當,歡迎指正。 原理解釋: 索引採用B樹原理,眾所周知,二叉排序樹是確定一個跟節點後,將比根節點大的資料放到右子節點,比根節點小的資料放到左子節點。而樹中的每

資料庫索引實現原理(面試問題:請說出資料庫索引實現原理

轉載:https://blog.csdn.net/hxpjava1/article/details/55803923 資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用B樹及其變種B+樹。 在資料之外

InnoDB索引實現原理以及注意點和建議

一、InnoDB實現原理 雖然InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM截然不同。因為InnoDB支援聚簇索引(主鍵索引),聚簇索引就是表,所以InnoDB不用像MyISAM那樣需要獨立的行儲存。也就是說,InnoDB的資料檔案本身就是索引檔案。 聚簇索引的每一個葉子節點都包含

資料庫索引實現原理以及優缺點

資料庫索引,在資料庫管理系統中是一個排序形式的資料結構,以協助快速查詢和更新資料庫表中資料。索引的實現通常使用B樹及其變種B+樹。 那麼為什麼要用B+樹來實現索引而不使用二叉搜尋樹或者平衡樹或者紅黑樹呢?要知道原因首先需要了解B樹的性質: 一個 m 階的B樹滿足以下條件:

【轉】MySQL—1、資料庫索引實現原理及查詢優化

MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。 使用索引的目的在於提高查詢效率,這篇文章梳理一下索引的實現原理和應用。 不同的儲存引擎索引實現的資料結構不同 MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,

MySQL數據備份 索引原理以及查詢優化

權限 示例 .cn 顯示 一個 物理 mysqld 恢復 cmd 補充 MySQL可視化(IDE)工具 我們之前對數據庫的操作都是通過cmd命令進行的比較繁瑣 那麽有沒有更漸變的方法去辦這個事呢? 答案事必須的 往下看吧。。。     navicat該工具是一

MySQL索引原理以及查詢優化

地址 存儲引擎 想要 方式 聯合 執行 圖書 解決 範圍查詢 一、介紹 1.什麽是索引? 一般的應用系統,讀寫比例在10:1左右,而且插入操作和一般的更新操作很少出現性能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些復雜的查詢操作,因此對查詢語句的優化顯然

索引原理SQL優化(轉載待整理)

索引的本質 MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。提取句子主幹,就可以得到索引的本質:索引是資料結構。 我們知道,資料庫查詢是資料庫的最主要功能之一。我們都希望查詢資料的速度能儘可能的快,因此資料庫系統的設計者會從查詢演算法的角度進行優化。最

資料庫索引底層原理優化

一、摘要 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型別,如BTree索引,雜湊索引,全文索引等等。為了避免混亂,本文將只關注於BTr

從B樹談到資料庫索引實現原理

4、如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識資料記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含欄位作為主鍵,這個欄位長度為6個位元組,型別為長整形

Oracle與Mysql等資料庫通用SQL優化技巧

a. 資料表的處理順序 oracle 在解析一個查詢語句FROM後面的一系列資料表是按照從右往左的順序進行的.也就是說最後的資料表將是最先被oracle處理的,所以我們在寫多個表關聯的查詢語句時,把資料量最小的表或者是經過條件篩選後得到資料量最小的表放到最後,資料量大的表就放在最前面. select col1

ORACLE索引使用總結(SQL優化及避免索引無效小技巧

  一:索引基本概念 oracle提供了兩種方式,從表中讀取所有行(即全表掃描),或者通過ROWID一次讀取一行; 如果只訪問大資料量表的5%的行,並且使用索引標識需要讀取的資料塊,這樣花費的 I/O 較少,索引對效能的改程序度: 1.取決於資料的選擇性 2.資料在表的資料塊中

資料庫索引實現底層原理2

強烈建議參閱連結:http://www.linezing.com/blog/?p=798#nav-1 說白了,索引問題就是一個查詢問題。。。 資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用B樹及其變種B+樹。 在

【搞定MySQL資料庫】:MySQL索引實現原理

本文轉發自:https://blog.csdn.net/a724888/article/details/78366383 本文主要轉載自幾篇關於MySQL資料庫索引相關的文章。可以相互參考著看。 目錄 1、MySQL索引型別 1.1、簡介 1.2、語句 1.3、索引型別

JAVA synchronized實現原理以及其中鎖優化的歸納總結

在java中存在兩種鎖機制,分別是synchronized和Lock。Lock介面和實現類是JDK5新增的內容,而synchronized在JDK6開始提供了一系列的鎖優化,下面總結一下synchronized的實現原理和涉及的一些鎖優化機制 1.sync

MySQL索引原理SQL優化

目錄 索引(Index) 索引的原理 b+樹 MySQL如何使用索引 如何優化 索引雖好,不可濫用 如何驗證索引使用情況?

(9)launcher3 之 外部 更換主題Theme APP demo 實現原理以及demo

解壓 work ace fontsize 思路 con 鎖屏 解壓文件夾 更新 先說下我的思路: luancher3裏面更換圖標的邏輯例如以下: 先從APP資源包裏查詢--數據庫查詢--其它地方查詢ICON 因此,我們僅僅須要把 從數據庫獲取ICON 代碼提前到 從A

數據庫優化以及SQL優化小結

需求 char 解決 通配符 () 表結構 date omsa 系列 優化數據庫的方法 1、選取最適用的字段屬性 MySQL可以很好的支持大數據量的存取,但是一般說來,數據庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中字

讀書筆記-MySQL運維內參08-索引實現原理1

復雜 ges ron 神奇 定位 覆蓋 image sql png B樹和B+樹的區別 1,B樹的葉子節點和內節點存在的都是數據行的所有信息,B+樹的內節點值存放鍵(索引)信息,數據都在葉子節點上。 2,由於B樹鍵和值的所有信息,所以每頁的存儲的數據行相對較少,隨數據發