MySQL查詢處理過程分析

MySQL查詢處理過程分析

介紹

查詢操作是關係型數據庫中使用最爲頻繁的操作,也是構成其它SQL語句(如:Delete、Update)的基礎。

要刪除或更新某些記錄時,首先要查詢出這些記錄,然後對其進行相應的操作。

查詢處理

SQL語言不同於其它編程語言(C、Java等),最明顯的不同體現在其處理代碼順序上。

在SQL語句中,第一個被處理的字句總是from字句。

舉例

(8)SELECT (9)DISTINCT<select_list>
(1)FROM table1
(3)JOIN table2..
(2)ON   <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH{cube|rollup}
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
(11)LIMIT <limit_numer>

備註:查詢執行順序如上

1、from:對from字句中的左表和右表執行笛卡兒積,產生虛表VT1
2、on:對虛表VT1進行on篩選,只選取符合條件的記錄作爲虛表VT2
3、join:如果指定了outer join(如left outer join、right outer join)那麼保留表中未匹配的行爲作爲外部行添加到虛擬表VT2中, 
產生虛擬表VT3.如果from字句包含兩個以上表,則對上一個連接生成的結果表VT3和下一個表重複執行步驟1和步驟3,
直到處理完所有表爲止。
4、where:對虛擬表VT3應用where過濾條件,篩選符合記錄保存到虛擬表VT4
5、group by:根據group by 字句中的列,對VT4中的記錄進行分組操作,產生虛擬表VT5
6、cube|rollup:對標VT5進行cube或rollup操作產生虛擬表VT6
7、對虛擬表VT6進行having過濾,篩選符合條件的記錄到虛擬表VT7
8、select:第二次執行select操作,選定指定的列到虛擬表VT8中
9、distinct:去除重複數據,產生虛擬表VT9
10、order by:將虛擬表VT9按照排序字段進行排序操作,產生虛擬表VT10
11、limit:取出指定行數的記錄,產生虛擬表VT11,即最終呈現給用戶的表。

案例展示

客戶表:
DROP TABLE IF EXISTS `customers`;
CREATE TABLE `customers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customer_id` int(11) NOT NULL,
  `city` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of customers
-- ----------------------------
INSERT INTO `customers` VALUES ('1', '1', '成都');
INSERT INTO `customers` VALUES ('2', '2', '杭州');
INSERT INTO `customers` VALUES ('3', '3', '上海');
INSERT INTO `customers` VALUES ('4', '4', '北京');

訂單表:
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `customer_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `orders` VALUES ('1', '1', '3');
INSERT INTO `orders` VALUES ('2', '2', '1');
INSERT INTO `orders` VALUES ('3', '3', '3');
INSERT INTO `orders` VALUES ('4', '4', '2');
INSERT INTO `orders` VALUES ('5', '5', '4');

查詢訂單數不小於2且用戶是上海的用戶信息?

SELECT customers.customer_id,COUNT(orders.order_id) AS order_num
FROM customers LEFT JOIN orders
ON customers.customer_id=orders.customer_id
WHERE customers.city="上海"
GROUP BY customers.customer_id
HAVING COUNT(orders.order_id)>=2
ORDER BY order_num
LIMIT 100;

備註:即使再複雜的SQL語句都是由簡單的SQL拼接出來的,所以寫SQL語句時,可以一邊寫一邊執行分析。

GROUP BY … HAVING …

GROUP BY ... HAVING ... 字句應該是這些當中比較難使用的篩選條件了

其使用原則:TODO

...

總結

複雜的SQL都是可以拆分成多條簡單SQL的,所以寫複雜SQL時要一步一步分析,一蹴而就比較難,除非你特別熟悉之後。

參考

1、MySQL技術內幕SQL編程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章