SQL優化之多表關聯查詢

慢SQL日誌裏看到一個三張表的關聯查詢,如下: 

1
2
3
4
SELECT COUNT(1) 
FROM refund_order_item i, artisan a, user 
WHERE u.userid = i.user_id
    AND a.artisan_id = i.artisan_id;

測試查詢時間: 

1
2
3
4
5
6
7
8
9
10
mysql> SELECT COUNT(1) 
    -> FROM refund_order_item i, artisan a, user 
    -> WHERE u.userid = i.user_id
    -> AND a.artisan_id = i.artisan_id;
+----------+
COUNT(1) |
+----------+
|   260605 |
+----------+
1 row in set (2.30 sec)

查看執行計劃:

1
2
3
4
5
6
7
8
9
10
11
mysql> explain SELECT COUNT(1) 
    -> FROM refund_order_item i, artisan a, user 
    -> WHERE u.userid = i.user_id
    -> AND a.artisan_id = i.artisan_id;
+----+-------------+-------+------------+--------+----------------------------+---------+---------+------------------+--------+----------+-------------+
| id | select_type       | table   | partitions   | type      | possible_keys        | key        | key_len | ref              | rows            | filtered | Extra       |
+----+-------------+-------+------------+--------+----------------------------+---------+---------+------------------+--------+----------+-------------+
|  1 | SIMPLE      | i      | NULL       ALL     | idx_user_id,idx_artisan_id       | NULL    NULL    NULL             | 255599 |   100.00 | NULL        |
|  1 | SIMPLE      | a     | NULL       | eq_ref | PRIMARY                               PRIMARY | 122   | hlj.i.artisan_id |      1     |   100.00 | Using index |
|  1 | SIMPLE      | u     | NULL       | eq_ref | userid                                    | userid    | 122      | hlj.i.user_id    |      1     |   100.00 | Using index |
+----+-------------+-------+------------+--------+----------------------------+---------+---------+------------------+--------+----------+-------------+

可以看到refund_order_item表沒有走索引。 

創建聯合索引:

1
ALTER TABLE refund_order_item ADD INDEX idx_aid_uid (artisan_id, user_id);

查看執行計劃:

1
2
3
4
5
6
7
8
explain SELECT COUNT(1)  FROM refund_order_item i, artisan a, user u  WHERE u.userid = i.user_id AND a.artisan_id = i.artisan_id;
+----+-------------+-------+------------+--------+----------------------------------------+-------------+---------+------------------+--------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys                                  | key         | key_len | ref              | rows   | filtered | Extra       |
+----+-------------+-------+------------+--------+----------------------------------------+-------------+---------+------------------+--------+----------+-------------+
|  1 | SIMPLE      | i      | NULL       index  | idx_user_id,idx_artisan_id,idx_aid_uid | idx_aid_uid | 244     | NULL             | 255599 |   100.00 | Using index |
|  1 | SIMPLE      | a     | NULL       | eq_ref | PRIMARY                                           PRIMARY     | 122     | hlj.i.artisan_id |      1 |   100.00 | Using index |
|  1 | SIMPLE      | u     | NULL       | eq_ref | userid                                                 | userid      | 122        | hlj.i.user_id    |      1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+----------------------------------------+-------------+---------+------------------+--------+----------+-------------+

可以看到執行計劃已經走索引。 

鄭州同濟醫院:http://jbk.39.net/yiyuanzaixian/zztjyy/

測試查詢時間: 

1
2
3
4
5
6
7
8
9
10
mysql> SELECT COUNT(1) 
    -> FROM refund_order_item i, artisan a, user 
    -> WHERE u.userid = i.user_id
    -> AND a.artisan_id = i.artisan_id;
+----------+
COUNT(1) |
+----------+
|   260605 |
+----------+
1 row in set (1.15 sec)


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