国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > 文庫 > 正文

一個left join SQL 簡單優化分析

2024-09-07 22:12:42
字體:
來源:轉載
供稿:網友
        有個關聯查詢的sql,需要2秒多,于是進行查看一番:
 
       SELECT
a.id,
a.brand_id,
a.series_id,
a.product_id,
a.material_id,
a.custom_category_id,
a.price,
a.product_url,
a.organ_id,
.....
FROM
pm_brand_xxxx a
LEFT JOIN pm_brand_yyyyy d ON a.series_id = d.id
WHERE
a.is_delete = 0
AND d.is_delete = 0
AND a.organ_id = 'Cxxx'
AND a.brand_id = 6491603
AND d.brand_id = 6491603
AND a.model_flag = 14;
mysql> show profile for query 4;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000072 |
| checking permissions | 0.000002 |
| checking permissions | 0.000002 |
| Opening tables       | 0.000011 |
| init                 | 0.000026 |
| System lock          | 0.000007 |
| optimizing           | 0.000016 |
| statistics           | 0.000142 |
| preparing            | 0.000018 |
| executing            | 0.000002 |
| Sending data         | 2.281192 |<<<<<<<執行的主要時間消耗
| end                  | 0.000007 |
| query end            | 0.000011 |
| closing tables       | 0.000011 |
| freeing items        | 0.000030 |
| logging slow query   | 0.000003 |
| logging slow query   | 0.000102 |
| cleaning up          | 0.000022 |
+----------------------+----------+
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys                                                                                                 | key                                                                       | key_len | ref   | rows  | filtered | Extra                                                                                                                                          |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | SIMPLE      | d     | NULL       | ref         | PRIMARY,idx_pm_yyyy_bid                                                                                        | idx_pm_yyyyy_bid                                                        | 9       | const |     1 |    10.00 | Using where                                                                                                                                    |
|  1 | SIMPLE      | a     | NULL       | index_merge | idx_pm_xxxx_sid,idx_pm_xxx_bid,idx_pm_brand_xxxx_organ                                                         | idx_pm_xxx_organ,idx_pm_brand_xxxx_bid                                   | 99,9    | NULL  | 11314 |     0.04 | Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where; Using join buffer (Block Nested Loop)                                        |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
      從執行計劃來看,d表是做了驅動表,a做了被驅動表
 
      d表 type = ref ,使用非唯一性索引或者唯一索引的前綴掃描,返回匹配某個單獨值的記錄行,這里使用了索引idx_pm_yyyyy_bid,該索引正是brand_id上的索引,
 
      即是說,在和a表的關聯中d先通過brand_id來查找記錄行,再通過相應記錄的id去和a表的series_id做匹配。
 
      我查看相應的記錄數,發現a表145萬的大表,d表是4075的小表。
 
a表
 
mysql> select count(*) from pm_xxxxxx;
 
+----------+
 
| count(*) |
 
+----------+
 
|  1459777 |
 
+----------+
 
1 row in set (0.27 sec)
 
d表:
 
mysql> select count(*) from pm_yyyyyy;
 
+----------+
 
| count(*) |
 
+----------+
 
|     4075 |
 
+----------+
 
1 row in set (0.00 sec)
 
而 a表是type=index_merge 索引合并,這里走了idx_pm_xxx_organ(organ_id),idx_pm_brand_xxxx_bid(brand_id) ,extra 是
 
Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where; Using join buffer (Block Nested Loop)
 
Using intersect正說明了這里使用了(idx_pm_xxxxx_organ,idx_pm_xxxx_bid)的交集
 
Using where 是用model_flag等這些其他條件的過濾
 
Using join buffer (Block Nested Loop) 說明使用BNL的算法進行匹配
 
 BNL 算法是將外層循環的行/結果集(驅動表)存入join buffer, 內層循環的每一行與整個buffer中的記錄做比較,從而減少內層循環的次數.
 
舉例來說,外層循環的結果集是100行,使用NLJ 算法需要掃描內部表100次,如果使用BNL算法,先把對Outer Loop表(外部表)每次讀取的10行記錄放到join buffer,然后在InnerLoop表(內部表)中直接匹配這10行數據,內存循環就可以一次與這10行進行比較, 這樣只需要比較10次,對內部表的掃描減少了9/10。所以BNL算法就能夠顯著減少內層循環表掃描的次數.
 
在這里就是d表中取得結果集分批放入buffer中與a表進行匹配。
 
而這個語句無論如何都要2秒中,也在我們的認識中小表驅動大表并沒錯,我的猜想應該就是在進行BNL時消耗了時間,表現到過程中就是 Sending data 的時間消耗增多。
 
吐槽的是mysql中貌似沒有什么辦法來多方面看查詢消耗了。

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 读书| 武鸣县| 尼木县| 北辰区| 铜鼓县| 色达县| 阳原县| 罗田县| 望谟县| 彩票| 东港市| 滁州市| 黎川县| 友谊县| 平度市| 政和县| 酉阳| 正安县| 光泽县| 赫章县| 晋中市| 建德市| 五台县| 连城县| 临沭县| 高雄市| 甘洛县| 宣化县| 南涧| 交城县| 乌鲁木齐县| 汽车| 二连浩特市| 收藏| 阳高县| 波密县| 五台县| 凤阳县| 辽中县| 太仆寺旗| 岫岩|