MySQL 查詢最大最小值優化

1. 假設你使用了Innodb存儲引擎
2. 假設你在innodb設定了主鍵(彙集索引)設計

3. 由於彙集索引頁面之間是經過雙向鏈表連接,頁按照主鍵的順序排序
每一個頁中的記錄也是經過雙向鏈表維護。彙集索引上存儲了主鍵的值
因爲B+樹的特性,最左端的葉子節點存儲最小的值,最右端的葉子節點存儲最大的值。

4. 最小值的通常方法:咱們能夠看到沒有使用key,設計的行299600行
root:employees 11:00 > select min(emp_no) from employees where gender='M';
+-------------+
| min(emp_no) |
+-------------+
| 10001 |
+-------------+
1 row in set (0.11 sec)排序

root:employees 11:07 > explain select min(emp_no) from employees where gender='M';
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 299600 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+索引

5. 利用上面的說明,取出最左端的葉子節點便可。此時咱們看到執行時間很短,雖然explain結果比較困惑!
root:employees 11:12 > select emp_no from employees USE INDEX(PRIMARY) where gender='M' limit 1;
+--------+
| emp_no |
+--------+
| 10001 |
+--------+
1 row in set (0.00 sec)it

root:employees 11:13 > explain select emp_no from employees USE INDEX(PRIMARY) where gender='M' limit 1;
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 299600 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+innodb

6. 一樣咱們執行max最大值的時候,能夠先倒排在取出第一個數據。由於頁之間經過雙向鏈表連接。
root:employees 11:18 > select max(emp_no) from employees where gender='M';
+-------------+
| max(emp_no) |
+-------------+
| 499999 |
+-------------+
1 row in set (0.22 sec)table

root:employees 11:18 > select emp_no from employees USE INDEX(PRIMARY) where gender='M' order by emp_no desc limit 1;
+--------+
| emp_no |
+--------+
| 499999 |
+--------+
1 row in set (0.00 sec)select

root:employees 11:18 > explain select emp_no from employees USE INDEX(PRIMARY) where gender='M' order by emp_no desc limit 1;
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | employees | index | NULL | PRIMARY | 4 | NULL | 1 | Using where |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+方法

7.咱們在查詢範圍的使用,也能夠利用B+樹的特性來迅速查詢到咱們想要的信息。由於B+樹的索引頁存儲了主鍵的範圍;
root:employees 11:22 > explain select emp_no from employees USE INDEX(PRIMARY) where gender='M' order by emp_no desc limit 1;
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | employees | index | NULL | PRIMARY | 4 | NULL | 1 | Using where |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+im

相關文章
相關標籤/搜索