精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

庖丁解牛-圖解MySQL 8.0優化器查詢解析篇

開發 前端
本文重點介紹了下優化器的基于規則的其中一部分優化,更多的偏重于SQL中的基本操作符,如表、列、函數、聚合、分組、排序等元素的解析和設置以及一些顯而易見的結構變化。

 [[423091]]

一、背景和架構

我們都知道,利用編寫程序來動態實現我們應用所需要的邏輯,從而程序執行時得到我們需要的結果。那么數據庫就是一種通過輸入SQL字符串來快速獲取數據的應用。當然,假設沒有數據庫這種系統應用,用程序如何實現呢?我們可能會發現,即使不管數據如何存儲、數據是否并發訪問,仍然需要不斷通過修改程序處理不同應用對數據的不同請求。比如大數據領域,我們通常通過非關系型數據庫的API,實現對數據的獲取。然而這種方式雖然入門簡單,但是維護極難,而且通用性不強,即使不斷進行軟件架構設計或者抽象重構,仍然需要不斷地變換應用,這也是為何非關系型數據庫回頭擁抱數據庫SQL優化器的原因。

SQL優化器本質上是一種高度抽象化的數據接口的實現,經過該設計,客戶可以使用更通用且易于理解的SQL語言,對數據進行操作和處理,而不需要關注和抽象自己的數據接口,極大地解放了客戶的應用程序。

本文就來通過圖形解說的方式介紹下MySQL 8.0 SQL優化器如何把一個簡單的字符串(SQL),變成數據庫執行器可以理解的執行序列,最終將數據返還給客戶。強大的優化器是不需要客戶關注SQL如何寫的更好來更快獲得需要的數據,因此優化器對原始SQL一定會做一些等價的變化。在 《MySQL 8.0 Server層最新架構詳解》 一文中我們重點介紹了MySQL最新版本關于Server層解析器、優化器和執行器的總體介紹,包括一些代碼結構和變化的詳細展示,并且通過simple_joins函數拋磚引玉展示了MySQL優化器在邏輯變換中如何簡化嵌套Join的優化。本文我們會一步一步帶你進入神奇的優化器細節,詳細了解優化器優化部分的每個步驟如何改變著一個SQL最終的執行。

本文基于最新MySQL8.0.25版本,因為優化器轉換部分篇幅比較長,我們分成兩篇文章來介紹,第一部分介紹基于基本結構的Setup和Resolve的解析轉換過程,第二部分介紹更為復雜的子查詢、分區表和連接的復雜轉換過程,大綱如下:

Setup and Resolve

  • setup_tables : Set up table leaves in the query block based on list of tables.

  • resolve_placeholder_tables/merge_derived/setup_table_function/setup_materialized_derived : Resolve derived table, view or table function references in query block.

  • setup_natural_join_row_types : Compute and store the row types of the top-most NATURAL/USING joins.

  • setup_wild : Expand all '*' in list of expressions with the matching column references.

  • setup_base_ref_items : Set query_block's base_ref_items.

  • setup_fields : Check that all given fields exists and fill struct with current data.

  • setup_conds : Resolve WHERE condition and join conditions .

  • setup_group : Resolve and set up the GROUP BY list.

  • m_having_cond->fix_fields : Setup the HAVING clause.

  • resolve_rollup : Resolve items in SELECT list and ORDER BY list for rollup processing .

  • resolve_rollup_item : Resolve an item (and its tree) for rollup processing by replacing items matching grouped expressions with Item_rollup_group_items and updating properties (m_nullable, PROP_ROLLUP_FIELD). Also check any GROUPING function for incorrect column.

  • setup_order : Set up the ORDER BY clause.

  • resolve_limits : Resolve OFFSET and LIMIT clauses.

  • Window::setup_windows1: Set up windows after setup_order() and before setup_order_final() .

  • setup_order_final: Do final setup of ORDER BY clause, after the query block is fully resolved.

  • setup_ftfuncs : Setup full-text functions after resolving HAVING .

  • resolve_rollup_wfs : Replace group by field references inside window functions with references in the presence of ROLLUP.

二、詳細轉換過程

轉換的整個框架是由Query_expression到Query_block調用prepare函數(sql/sql_resolver.cc)并且根據不同轉換規則的要求自頂向下或者自底向上的過程。

1.傳遞null到join的內表列表(propagate_nullability)

prepare開始先要處理nullable table,它指的是table可能包含全為null的row,根據JOIN關系(top_join_list)null row可以被傳播。如果能確定一個table為nullable會使得一些優化退化,比如access method不能為EQ_REF、outer join不能優化為inner join等。

2.解析設置查詢塊的leave_tables(setup_tables)

  1. SELECT 
  2.   t1.c1 
  3. FROM t1, 
  4.      (SELECT 
  5.        t2.c1 
  6.      FROM t2, 
  7.           (SELECT 
  8.             t3.c1 
  9.           FROM t3 
  10.           UNION 
  11.           SELECT 
  12.             t4.c1 
  13.           FROM t4) AS t3a) AS t2a; 

未在setup_table調用之前,每個Query_block的leaf_tables是為0的。

該函數的作用就是構建leaf_tables,包括base tables和derived tables列表,用于后續的優化。setup_tables并不會遞歸調用,而是只解決本層的tables,并統計出本層derived table的個數。但是隨后會調用resolve_placeholder_tables()->resolve_derived()->derived(Query_expression)::prepare->Query_block::prepare來專門遞歸處理derived table對應的Query_expression。

接下來我們根據prepare的調用順序,繼續看下針對于derived table處理的函數resolve_placeholder_tables。

3.解析查詢塊Derived Table、View、Table函數 (resolve_placeholder_tables)

這個函數用于對derived table、view和table function的處理,如果該table已經merged過了,或者是由于使用transform_grouped_to_derived()被調用到,已經決定使用materialized table方式,則直接忽略。

前面已經介紹過resolve_derived()的作用,我們重點介紹merge_derived()函數,merge_derived是改變Query_expression/Query_block框架結構,將derived table或者view合并到到query block中。

merge_derived 處理和合并Derived table

1)merge_derived transformation的先決條件

  • 外層query block是否允許merge(allow_merge_derived)

    • 外層query block為nullptr

    • 外層query expression的子查詢為nullptr,derived table是第一層子查詢

    • 外層的外層query block可以allow_merge_derived=true,或者不包括外層的外層query block話是否為SELECT/SET

  • 外層lex是否可以支持merge(lex->can_use_merged()+lex->can_no_use_merged())

  • derived table是否已經被標記為需要物化materialize,比如創建視圖的方法是CREATE ALGORITHM=TEMPTABLE VIEW(derived_table->algorithm == VIEW_ALGORITHM_TEMPTABLE)

  • 整個dervived table所在的查詢表達式單元中,不能是(Query_expression::is_mergeable() ):

    • Union查詢

    • 包含聚集、HAVING、DISTINCT、WINDOWS或者LIMIT

    • 沒有任何table list

  • HINT或者optimizer_switch沒有禁止derived_merge;

  • heuristic建議合并(derived_query_expressionmerge_heuristic());

    • 如果derived table包含的子查詢SELECT list依賴于自己的列時,不支持;

    • 如果是dependant subquery需要多次執行時,不支持;

  • derived table中如果查詢塊包含SEMI/ANTI-JOIN,并指定STRAIGHT_JOIN時,不支持;

  • 如果合并的derived table和現有query block的leaf table count大約 MAX_TABLES時,不支持;

2)merge_derived transformation的轉換過程

  • 利用derived_table->nested_join結構來輔助處理OUTER JOIN的情況。

  • 把derived table中的表merge到NESTED_JOIN結構體(derived_table->merge_underlying_tables())。

  • 將derived table中的所有表連接到父查詢的table_list列表中,同時把derived table從父查詢中刪除。

  • 對父查詢的所有相關數據結構進行重新計算(leaf_table_count、derived_table_count、table_func_count、materialized_derived_table_count、has_sj_nests、has_aj_nests、partitioned_table_count、cond_count、between_count、select_n_having_items)。

  • 傳播設置父查詢OPTION_SCHEMA_TABLE(add_base_options())和如果是外查詢JOIN的內表,傳播設置nullable屬性(propagate_nullability())。

  • 合并derived table的where條件到外查詢中(merge_where())。

  • 建立對derived table需要獲取的列的引用(create_field_translation())。

  • 將Derived table的結構從父查詢中刪除(exclude_level())。

  • 將derived table中的列或者表的重命名合并到父查詢(fix_tables_after_pullout()/repoint_contexts_of_join_nests())。

  • 因為已經把derived table中包含的表merge到了父查詢,所以需要對TABLE_LIST中的表所在的位置進行重新定位(remap_tables())。

  • 將derived table合并到父查詢之后,需要重新修改原來derived table中所有對derived table中所有列的引用(fix_tables_after_pullout())。

  • 如果derived table中包含ORDER BY語句,如果滿足下列條件,derived table將會保留ORDER BY并合并到父查詢中,其他情況ORDER BY將會被忽略掉:

    • 如果父查詢允許排序并且正好是只有derived table

    • 不是一個UNION

    • 可以有WHERE條件,但是不能有group by或聚合函數

    • 本身并不是有序的

過程簡化為:

merge_derived 圖解過程

看起來官方的derived merge還是不夠完美,無法自底向上的遞歸merge

包含的opt trace:

  1. trace_derived.add_utf8_table(derived_table) 
  2.        .add("select#", derived_query_block->select_number) 
  3.        .add("merged"true); 
  4.  
  5.  
  6. trace_derived.add_alnum("transformations_to_derived_table""removed_ordering"); 

該優化可以通過set optimizer_switch="derived_merge=on/off"來控制。

setup_materialized_derived 設置物化Derived Table

對于剩下不能采用 merge 算法的 derived table ,會轉為materialize 物化方式去處理。但此時只是做一些變量設置等預處理,實際的物化執行是在executor階段執行。

  • setup_materialized_derived_tmp_table(): 設置一個臨時表包含物化Derived Table的所有行數據。

  • check_materialized_derived_query_blocks(): 設置屬于當前Derived Table所在的查詢塊結構。
  1. trace_derived.add_utf8_table(this
  2.        .add("select#", derived->first_query_block()->select_number) 
  3.        .add("materialized"true); 

setup_table_function 處理表函數

如果 query block 中有 table function,整個過程會處理兩遍。第一遍會跳過 table function 的 table ,第二遍才專門再對table function 的 table 執行一遍上述邏輯。這里的考慮應該是先 resolve 了外部環境(相對于table function),因為有可能函數參數會有依賴外部的 derived table。

  1. trace_derived.add_utf8_table(this
  2.        .add_utf8("function_name", func_name, func_name_len) 
  3.        .add("materialized"true); 

4.將SELECT *的通配符展開成具體的fields(setup_wild)

5.建立Query_block級別的base_ref_items(setup_base_ref_items)

base_ref_items記錄了所有Item的位置,方便查詢塊的其他Item可以進行引用,或者通過Item_ref及其Item_ref子類進行直接引用,例如子查詢的引用(Item_view_ref)、聚合函數引用(Item_aggregate_ref)、外查詢列的引用(Item_outer_ref)、subquery 子查詢產生NULL value的引用輔助(Item_ref_null_helper)。

舉例說明比較復雜的Item_outer_ref:

6.對select_fields進行fix_fields()和列權限檢查(setup_fields)

下圖是比較復雜的帶子查詢的fixed field過程。有些field和表關聯,有的要添加相應的Item_xxx_ref引用。

7.解析和fixed_fields WHERE條件和Join條件(setup_conds)

setup_join_cond如果有nested_join會遞歸調用setup_join_cond進行解析和設置。這里也順帶介紹下simplify_const_condition函數的作用,如果發現可以刪除的const Item,則會用Item_func_true/Item_func_false來替代整個的條件,如圖。

8.解析和設置ROLLUP語句(resolve_rollup)

在數據庫查詢語句中,在 GROUP BY 表達式之后加上 WITH ROLLUP 語句,可以使得通過單個查詢語句來實現對數據進行不同層級上的分析與統計。

  1. SELECT YEAR, 
  2.        country, 
  3.        product, 
  4.        SUM(profit) AS profit 
  5. FROM sales 
  6. GROUP BY YEAR, 
  7.          country, 
  8.          product WITH ROLLUP; 
  9.  
  10.  
  11. +------+---------+------------+--------+ 
  12. | year | country | product    | profit | 
  13. +------+---------+------------+--------+ 
  14. 2000 | Finland | Computer   |   1500 | 
  15. 2000 | Finland | Phone      |    100 | 
  16. 2000 | Finland | NULL       |   1600 | 
  17. 2000 | India   | Calculator |    150 | 
  18. 2000 | India   | Computer   |   1200 | 
  19. 2000 | India   | NULL       |   1350 | 
  20. 2000 | USA     | Calculator |     75 | 
  21. 2000 | USA     | Computer   |   1500 | 
  22. 2000 | USA     | NULL       |   1575 | 
  23. 2000 | NULL    | NULL       |   4525 | 
  24. 2001 | Finland | Phone      |     10 | 
  25. 2001 | Finland | NULL       |     10 | 
  26. 2001 | USA     | Calculator |     50 | 
  27. 2001 | USA     | Computer   |   2700 | 
  28. 2001 | USA     | TV         |    250 | 
  29. 2001 | USA     | NULL       |   3000 | 
  30. 2001 | NULL    | NULL       |   3010 | 
  31. | NULL | NULL    | NULL       |   7535 | 
  32. +------+---------+------------+--------+ 
  33.  
  34.  
  35. 相當于做了下面的查詢: 
  36.  
  37.  
  38. SELECT * 
  39. FROM 
  40.   (SELECT YEAR, 
  41.           country, 
  42.           product, 
  43.           SUM(profit) AS profit 
  44.    FROM sales 
  45.    GROUP BY YEAR, 
  46.             country, 
  47.             product 
  48.    UNION ALL SELECT YEAR, 
  49.                     country, 
  50.                     NULL, 
  51.                     SUM(profit) AS profit 
  52.    FROM sales 
  53.    GROUP BY YEAR, 
  54.             country 
  55.    UNION ALL SELECT YEAR, 
  56.                     NULL, 
  57.                     NULL, 
  58.                     SUM(profit) AS profit 
  59.    FROM sales 
  60.    GROUP BY YEAR 
  61.    UNION ALL SELECT NULL, 
  62.                     NULL, 
  63.                     NULL, 
  64.                     SUM(profit) AS profit 
  65.    FROM sales) AS sum_table 
  66. ORDER BY YEAR, country, product; 
  67.  
  68.  
  69. +------+---------+------------+--------+ 
  70. | YEAR | country | product    | profit | 
  71. +------+---------+------------+--------+ 
  72. | NULL | NULL    | NULL       |   7535 | 
  73. 2000 | NULL    | NULL       |   4525 | 
  74. 2000 | Finland | NULL       |   1600 | 
  75. 2000 | Finland | Computer   |   1500 | 
  76. 2000 | Finland | Phone      |    100 | 
  77. 2000 | India   | NULL       |   1350 | 
  78. 2000 | India   | Calculator |    150 | 
  79. 2000 | India   | Computer   |   1200 | 
  80. 2000 | USA     | NULL       |   1575 | 
  81. 2000 | USA     | Calculator |     75 | 
  82. 2000 | USA     | Computer   |   1500 | 
  83. 2001 | NULL    | NULL       |   3010 | 
  84. 2001 | Finland | NULL       |     10 | 
  85. 2001 | Finland | Phone      |     10 | 
  86. 2001 | USA     | NULL       |   3000 | 
  87. 2001 | USA     | Calculator |     50 | 
  88. 2001 | USA     | Computer   |   2700 | 
  89. 2001 | USA     | TV         |    250 | 
  90. +------+---------+------------+--------+ 

排序由于有NULL的問題,所以分級匯總的效果非常難弄,而且group 列不同改變,SQL復雜度來回變化,而ROLLUP很簡單就可以實現效果,下面看下rollup在解析過程做了什么樣的轉換達到了意想不到的效果。

9.解析和設置GROUP BY/ORDER BY語句(setup_group/setup_order)

其中一個函數find_order_in_list(): 嘗試在select fields里去尋找可以映射的列,否則就得在最后投影的all fields里加上當前列,同時也做fix_fields。

  • m_having_cond->fix_fields : 對having條件進行fixed_fields。

  • resolve_limits : 處理OFFSET和LIMIT子句(offset_limit和select_limit的Items)。

  • setup_ftfuncs : 如果有full-text的函數,對相關Item進行fix_fields。

  • remove_redundant_subquery_clause : 對于Table Subquery的表達式,通常是IN/ANY/ALL/EXISTS/etc,如果沒有聚合函數和Having子句,通常可以考慮刪除不必要的ORDER/DISTINCT/GROUP BY。該函數支持三種REMOVE_ORDER | REMOVE_DISTINCT | REMOVE_GROUP,如果是SINGLEROW_SUBS的子查詢,只考慮刪除REMOVE_ORDER。

    1. select c1 from t1 where t1.c2 in (select distinct c1 from t2 group by c1, c2 order by c1); 
    2. 轉化為 => 
    3. select c1 from t1 where t1.c2 in (select c1 from t2); 
  • 處理是否可以刪除不必要的distinct語句,刪除的條件就是GROUP BY的列都在SELECT列表中,并且沒有ROLLUP和Window函數。

    1. is_grouped() && hidden_group_field_count == 0 && olap == UNSPECIFIED_OLAP_TYPE 

例如場景:

  1. SELECT DISTINCT c1, max(c2) from t1 group by c1; 

10.解析和設置Window函數(Window::setup_windows1)

  1. SELECT id, 
  2.        release_year, 
  3.        rating, 
  4.        avg(rating) over(PARTITION BY release_year) AS year_avg 
  5. FROM tw; 
  6.  
  7.  
  8. +------+--------------+--------+-------------------+ 
  9. | id   | release_year | rating | year_avg          | 
  10. +------+--------------+--------+-------------------+ 
  11. |    1 |         2015 |      8 |               8.5 | 
  12. |    3 |         2015 |      9 |               8.5 | 
  13. |    2 |         2015 |    8.5 |               8.5 | 
  14. |    4 |         2016 |    8.2 |               8.3 | 
  15. |    5 |         2016 |    8.4 |               8.3 | 
  16. |    6 |         2017 |      7 |                 7 | 
  17. +------+--------------+--------+-------------------+ 

執行的過程和結果類似于下圖:

我們看下它在開始Query_block::prepare解析過程做了哪些事情:

select_lex->m_windows 不為空,就調用  Window::setup_windows1

  • 遍歷window函數列表,調用resolve_window_ordering來解析m_partition_by和m_order_by

  • 處理inter-window的引用關系(如WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)),但必須是一個有向無環圖(DAG)

  • 重新遍歷檢查是否唯一名字check_unique_name、創建window partition by和window order by的引用items

  • 檢查窗口函數特征(Window::check_window_functions1(THD *thd, _block *select))

    • 首先判斷的是當前是靜態窗口還是動態窗口;靜態窗口即判斷了 frame 的定義是否有定義上下邊界。 m_static_aggregates  為 true, 意味著是靜態窗口,同時對每一個分區都可以進行一次評估。如果  ma_static_aggregates  為 false, 則進一步判斷其滑動窗口使用的是基于范圍還是基于行。  m_row_optimizable  基于行  m_range_optimizable  基于范圍 

    • 獲取聚合函數作為窗口函數時候窗口的特殊規格要求 wfs->check_wf_semantics1(thd, select, &reqs)  這個方法其實就是判斷是不是需要row_buffer作為評估,如果我們只看當前分區的行無法進行正確的計算不需要,而需要看之后的或者之前的行,就需要使用row_buffer。

三、綜述

本文重點介紹了下優化器的基于規則的其中一部分優化,更多的偏重于SQL中的基本操作符,如表、列、函數、聚合、分組、排序等元素的解析和設置以及一些顯而易見的結構變化。下一篇文章我們將繼續介紹子查詢、分區表和JOIN操作的轉換部分,敬請期待。

責任編輯:張燕妮 來源: 阿里技術
相關推薦

2021-09-14 09:35:34

MySQL查詢解析優化器

2021-01-20 14:06:54

華為云

2025-10-27 01:33:00

CPU全鏈路命令

2011-12-14 18:28:10

惠普

2025-09-24 08:03:22

2018-03-14 17:28:51

WOT測試基礎架構茹炳晟

2009-01-22 12:15:03

NetApp數據管理企業管理

2021-11-09 10:34:46

InnoDB數據并發

2021-11-05 10:07:40

InnoDB磁盤Redolog

2024-01-03 09:48:15

駕駛技術架構

2021-09-06 06:45:06

Webpack優化MindMaster

2018-05-23 13:47:28

數據庫PostgreSQL查詢優化

2018-05-25 15:04:57

數據庫PostgreSQL查詢優化器

2017-12-20 08:58:14

LevelDB概覽思路

2010-06-12 15:31:04

MySQL查詢優化

2011-02-28 14:37:43

GitLinux版本控制

2025-09-04 08:53:38

2025-01-15 12:48:30

2023-03-29 08:13:48

MySQL檢索成本

2011-02-25 14:35:00

點贊
收藏

51CTO技術棧公眾號

亲子乱一区二区三区电影| 日韩一区二区三区免费看| 国产精品.com| 国产精品久久久久久99| 中文有码一区| 欧美三级午夜理伦三级中视频| 亚洲国产精品www| 精品人妻一区二区三区三区四区 | 欧美在线播放一区| 中文字幕av在线免费观看| 91亚洲一区| 亚洲第一视频在线观看| 2022亚洲天堂| 免费在线视频欧美| 国产在线看一区| 91国产视频在线| 国产探花在线视频| 日韩av资源网| 欧美一区二区三区四区五区| 啊啊啊一区二区| 国产高清一区二区三区视频| av午夜一区麻豆| 成人精品视频99在线观看免费 | 欧美性xxxx极品hd满灌| 一区二区三区欧美成人| 亚洲欧美丝袜中文综合| 韩国精品免费视频| 人体精品一二三区| 久久黄色小视频| 久久精品av| 亚洲精品国产suv| 在线一区二区不卡| 欧美日韩不卡| 欧美色播在线播放| 日本大片免费看| 在线观看完整版免费| 99久久精品国产网站| 91丝袜美腿美女视频网站| 69视频免费看| 裸体一区二区| 18性欧美xxxⅹ性满足| 黄色录像二级片| 精品一二三区| 国产视频综合在线| 少妇激情一区二区三区视频| 国产不卡精品在线| 欧美老年两性高潮| 五月婷婷之婷婷| 日韩欧美精品一区二区综合视频| 精品福利视频导航| www.av片| a'aaa级片在线观看| 一区二区三区日韩精品| 亚洲小说欧美另类激情| 麻豆传媒视频在线| 中文字幕一区二区三区在线播放 | 高清av在线| 久久久久久免费| 欧美精品成人一区二区在线观看 | 一级片免费网址| 欧美视频二区| 欧美精品福利视频| 国产精品99无码一区二区| 欧美日韩国产在线一区| 欧美美女操人视频| 麻豆一区二区三区精品视频| 国产综合自拍| 午夜精品一区二区三区视频免费看 | 97精品人妻一区二区三区| 日本成人在线不卡视频| 国产精品老女人视频| 中文亚洲av片在线观看| 美女网站视频久久| 国产日韩欧美黄色| 国产日韩一级片| 国产成人亚洲精品青草天美| 国产91精品入口17c| 日本美女一级视频| 2024国产精品视频| 日韩中文字幕一区| 日本精品在线| 一区av在线播放| 男人日女人bb视频| 国产电影一区二区三区爱妃记| 欧美日韩在线一区二区| 久久精品国产99久久99久久久| 日本精品视频| 亚洲精品黄网在线观看| 国产一级久久久久毛片精品| 国产精品91一区二区三区| 久久久久在线观看| 精品久久久久久久久久久久久久久久久久| 蜜桃一区二区三区在线| 成人av资源网| 超碰国产在线观看| 亚洲伊人伊色伊影伊综合网| 国产精品免费成人| 天堂久久av| 亚洲人午夜精品免费| 91视频综合网| 亚洲综合国产| 51国偷自产一区二区三区的来源| 婷婷开心激情网| 国产精品电影一区二区| 一区二区传媒有限公司| 91精品在线免费视频| 亚洲精品成人免费| 三级在线观看免费大全| 亚洲主播在线| 俄罗斯精品一区二区| 777电影在线观看| 天天色综合天天| 999久久久精品视频| 日韩欧美黄色| 欧美激情xxxxx| 亚洲视频在线观看一区二区| 99国产精品久久久久久久久久| 亚洲图片欧洲图片日韩av| 国产白丝在线观看| 欧美亚洲自拍偷拍| 极品白嫩丰满美女无套| 亚洲高清资源在线观看| 97成人精品视频在线观看| www.伊人久久| 国产福利91精品| 国产亚洲欧美另类一区二区三区 | 高清一区二区| 亚洲区一区二区| 欧美成人aaa片一区国产精品| 久久精品主播| 国产精品入口免费| 成人日日夜夜| 欧美三级日韩在线| 人人妻人人澡人人爽人人精品 | 偷拍中文亚洲欧美动漫| 欧美一区二区性放荡片| 色噜噜日韩精品欧美一区二区| 亚洲精彩视频| 国产欧美精品va在线观看| 神马午夜在线观看| 亚洲最色的网站| 波多野结衣中文字幕在线播放| 精品视频亚洲| 国产成人精品国内自产拍免费看 | 麻豆精品一区二区综合av| 久久香蕉综合色| 欧美xxx黑人xxx水蜜桃| 日韩一卡二卡三卡国产欧美| 亚洲精品午夜视频| 亚洲少妇诱惑| 国产亚洲欧美一区二区 | 乱亲女秽乱长久久久| 中文字幕第三页| 久久女同精品一区二区| 精品久久久久久无码中文野结衣| 亚瑟国产精品| 深夜精品寂寞黄网站在线观看| 五月婷婷视频在线| 26uuu精品一区二区| 777精品久无码人妻蜜桃| 日韩欧美高清一区二区三区| 久久综合久久88| 91久久精品国产91性色69| 亚洲国产精品国自产拍av| 欧美国产亚洲一区| 精品国产123区| 日本道色综合久久影院| 天天在线女人的天堂视频| 婷婷国产在线综合| 91九色蝌蚪porny| 黄色精品网站| 国产精品一区二区免费| 韩国中文字幕在线| 精品国产精品网麻豆系列| 国产亚洲欧美久久久久| 成人免费视频caoporn| www.亚洲视频.com| 久久久免费毛片| 日本亚洲精品在线观看| 久久手机免费观看| 在线日韩av片| 成人欧美一区二区三区黑人一| 美女视频黄 久久| 特级毛片在线免费观看| 欧美a级大片在线| 久久精品国产亚洲精品| 亚洲成人第一区| 午夜国产精品影院在线观看| 亚洲av无码国产精品麻豆天美| 日本欧美韩国一区三区| 五月天男人天堂| 91成人午夜| 日韩av免费在线| 亚洲精品在线视频| 最新中文字幕第一页| 综合分类小说区另类春色亚洲小说欧美| 99国产精品久久久久久| 欧美日韩亚洲三区| 免费在线国产精品| 超碰国产精品一区二页| 久久免费国产视频| 黄色小视频在线免费观看| 欧美日韩亚洲综合在线 | 日韩暖暖在线视频| 超碰免费97在线观看| 精品福利一区二区三区| 天天干天天操天天操| 一区二区在线观看视频| 麻豆精品免费视频| 国产传媒久久文化传媒| 免费看黄色一级大片| 欧美国产高潮xxxx1819| 蜜桃av噜噜一区二区三| 成人乱码手机视频| 奇米四色中文综合久久| 伊人在线视频| 亚洲美女av在线播放| 一级片免费观看视频| 亚洲高清在线视频| 国产在线观看免费视频软件| av福利精品导航| 人妻少妇偷人精品久久久任期| 欧美在线综合| 日韩一级特黄毛片| 日本高清免费电影一区| 国产高清精品一区二区三区| av资源亚洲| 97久久精品国产| 国产理论在线观看| 国产亚洲精品成人av久久ww| 人妻少妇一区二区三区| 91精品中文字幕一区二区三区| 老熟妇一区二区三区啪啪| 亚洲地区一二三色| 成人高潮免费视频| 国产偷v国产偷v亚洲高清| 午夜男人的天堂| 狠狠色丁香婷婷综合| 黄色片久久久久| 亚洲激情另类| 日本美女爱爱视频| 久久香蕉国产| 一区二区精品在线观看| 久久不见久久见国语| 国产一区不卡在线观看| 麻豆精品久久| 成人在线激情视频| 精品午夜av| 成人国产精品一区二区| 国产成人精品123区免费视频| 97在线视频免费看| 超碰97免费在线| 91高清在线免费观看| 2020av在线| 午夜精品一区二区三区av| 国产区美女在线| 欧美理论片在线观看| 中国日本在线视频中文字幕| 色偷偷88888欧美精品久久久| 男女网站在线观看| 亚洲欧美另类在线观看| 日产精品久久久久久久性色| 精品三级在线观看| 天天摸天天干天天操| 免费日韩精品中文字幕视频在线| 成人久久18免费网站麻豆| 欧美精品aaaa| 巨乳诱惑日韩免费av| 久久久久久久久久久久91| 免费人成黄页网站在线一区二区| 黄色国产小视频| 一本色道久久综合一区| 熟妇人妻无乱码中文字幕真矢织江| 丝袜脚交一区二区| 国产wwwxx| 麻豆精品在线看| www.四虎在线| 99精品欧美一区二区三区小说| 熟女人妻在线视频| 久久久久亚洲蜜桃| 亚洲毛片亚洲毛片亚洲毛片| 亚洲欧美视频在线观看视频| 日韩a级片在线观看| 亚洲一区二区五区| 青青国产在线观看| 欧美性xxxx极品高清hd直播| 在线观看亚洲一区二区| 欧美一区二区女人| 欧美 中文字幕| 国产视频在线观看一区二区| 免费黄色电影在线观看| 欧美男插女视频| 亚洲电影观看| 国产精品一区二区三区久久久 | 国产精品污www在线观看| youjizz亚洲女人| 亚洲猫色日本管| 日韩欧美亚洲视频| 欧美在线你懂的| 一区二区视频免费观看| 亚洲国产天堂久久国产91| 东热在线免费视频| 欧美理论电影在线播放| 欧美人与性动交xxⅹxx| 91文字幕巨乱亚洲香蕉| 色婷婷av一区二区三区丝袜美腿| 日产国产精品精品a∨| 亚洲影视一区| 日韩中文字幕免费在线| 国产在线国偷精品产拍免费yy| 中文字幕乱码一区| 国产精品久久福利| 国产欧美一区二区三区在线看蜜臂| 欧美日韩国产综合一区二区| 亚洲国产www| 伊人一区二区三区久久精品| av资源在线播放| 91精品久久久久久久久久另类| 国产乱论精品| youjizz.com亚洲| 亚洲少妇一区| 动漫av在线免费观看| 国产精品婷婷午夜在线观看| 日韩污视频在线观看| 欧美色图在线观看| 男女视频在线观看| 午夜精品美女自拍福到在线| 日韩毛片免费看| 精选一区二区三区四区五区| 欧美日韩亚洲三区| 香蕉视频999| 久久精品视频免费| 久久精品国产亚洲av香蕉| 欧美一区二区在线看| 国产精品视频二区三区| 97视频免费在线观看| 亚洲国产中文在线| 91xxx视频| 久久精品免费观看| 在线观看国产精品一区| 福利一区福利二区微拍刺激| 黄片毛片在线看| 九色精品免费永久在线| 天堂综合在线播放| 相泽南亚洲一区二区在线播放| 日韩高清欧美激情| 久久无码人妻精品一区二区三区| 亚洲图片欧美色图| 性一交一乱一色一视频麻豆| 欧美人在线观看| 国产精品1区| 欧美精品一区二区性色a+v| 日韩和欧美一区二区| 亚洲天堂岛国片| 91黄视频在线观看| 你懂的视频在线免费| 韩国三级电影久久久久久| 欧美性生活一级片| 自拍日韩亚洲一区在线| 成人少妇影院yyyy| 亚洲黄色免费观看| 亚洲欧美国产视频| 丁香六月综合| 欧美日韩一区在线视频| 奇米影视一区二区三区小说| 级毛片内射视频| 欧美视频三区在线播放| 91福利在线视频| 国产主播喷水一区二区| 香蕉综合视频| 99精品视频国产| 国产精品国产精品国产专区不蜜| 一级黄色小视频| 久久久久久久久国产精品| 久9re热视频这里只有精品| 无码专区aaaaaa免费视频| 成人h动漫精品| 欧美成人精品网站| 久久视频免费在线播放| 日韩视频一二区| 国产二区视频在线播放| 国产色产综合色产在线视频 | 欧美日韩一区二区三区四区五区| 国产高清免费在线播放| 91色在线观看| 亚洲精品美女91| 在线小视频你懂的| 日韩亚洲欧美一区| 美女高潮视频在线看| 日韩欧美视频一区二区| 国产一区在线精品| 国产精品第一页在线观看| 亚洲欧美另类中文字幕| 玖玖精品在线| 免费国产黄色网址| 国产欧美日产一区| 国产高潮在线观看| 国产v综合ⅴ日韩v欧美大片 | 久久99国产精品二区高清软件| 中文字幕av久久|