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

聊一聊 MySQL 相關(guān)子查詢

數(shù)據(jù)庫 MySQL
這一篇我們就來聊聊不相關(guān)子查詢轉(zhuǎn)換為相關(guān)子查詢,以及相關(guān)子查詢執(zhí)行的那些事。

子查詢系列的上一篇文章??《MySQL 不相關(guān)子查詢怎么執(zhí)行?》???提到過,MySQL 有可能把不相關(guān)?子查詢轉(zhuǎn)換為相關(guān)子查詢。

這一篇我們就來聊聊不相關(guān)子查詢轉(zhuǎn)換為相關(guān)子查詢,以及相關(guān)子查詢執(zhí)行的那些事。

本文不相關(guān)子查詢都是指的 IN 子查詢,內(nèi)容基于 MySQL 8.0.29 源碼。

正文

1、explain type、ref 列的顯示邏輯

本文示例 SQL 中的表,都來自于官方提供的測試數(shù)據(jù)庫 sakila,下載鏈接如下:https://downloads.mysql.com/docs/sakila-db.tar.gz

相關(guān)子查詢有兩種來源(也許還有其它來源?):

  • 一種是我們純手工打造的。
  • 另一種就是從不相關(guān)子查詢轉(zhuǎn)換來的了。

通過 explain 查看這兩種 SQL 的執(zhí)行計(jì)劃,子查詢的 type、ref 列可能一樣,也可能不一樣,難免讓人困惑。

我們先來弄清楚兩種 SQL 的 explain 結(jié)果中,子查詢的 type、ref 列為什么會顯示不一樣?

示例 SQL 1:

-- 為了保證 EXISTS 子查詢不會轉(zhuǎn)換為半連接
-- 先把半連接優(yōu)化關(guān)閉
SET optimizer_switch="semijoin=off";

-- 純手工打造的相關(guān)子查詢
EXPLAIN SELECT * FROM city
WHERE city_id < 100 AND EXISTS (
SELECT city_id FROM address
WHERE city.city_id = address.city_id
)

-- explain 結(jié)果如下,為了方便查看
-- 我調(diào)整了 ref 列的位置
-- 并且刪掉了 partitions 列
+----+--------------------+---------+-------+---------------------+----------------+----------------+---------+------+----------+-------------+
| id | select_type | table | type | ref | possible_keys | key | key_len | rows | filtered | Extra |
+----+--------------------+---------+-------+---------------------+----------------+----------------+---------+------+----------+-------------+
| 1 | PRIMARY | city | range | <null> | PRIMARY | PRIMARY | 2 | 99 | 100.0 | Using where |
| 2 | DEPENDENT SUBQUERY | address | ref | sakila.city.city_id | idx_fk_city_id | idx_fk_city_id | 2 | 1 | 100.0 | Using index |
+----+--------------------+---------+-------+---------------------+----------------+----------------+---------+------+----------+-------------+

子查詢 type 列的值為 ref,表示 address 表使用 idx_fk_city_id 索引(key 列的值)進(jìn)行等值范圍掃描。

子查詢 ref 列的值為 sakila.city.city_id,表示 where 條件中 address.city_id 字段值來源于主查詢 city 表的 city_id 字段值。

示例 SQL 2:

-- 為了保證 IN 子查詢不會轉(zhuǎn)換為半連接
-- 先把半連接優(yōu)化關(guān)閉
SET optimizer_switch="semijoin=off";

-- 不相關(guān)子查詢
EXPLAIN SELECT * FROM city
WHERE city_id < 100 AND city_id IN (
SELECT city_id FROM address
)

-- explain 結(jié)果如下
-- 可以看到不相關(guān)子查詢已經(jīng)轉(zhuǎn)換為相關(guān)子查詢了
-- 為了方便查看,我調(diào)整了 ref 列的位置
-- 并且刪掉了 partitions 列
+----+--------------------+---------+----------------+--------+----------------+----------------+---------+------+----------+-------------+
| id | select_type | table | type | ref | possible_keys | key | key_len | rows | filtered | Extra |
+----+--------------------+---------+----------------+--------+----------------+----------------+---------+------+----------+-------------+
| 1 | PRIMARY | city | range | <null> | PRIMARY | PRIMARY | 2 | 99 | 100.0 | Using where |
| 2 | DEPENDENT SUBQUERY | address | index_subquery | func | idx_fk_city_id | idx_fk_city_id | 2 | 1 | 100.0 | Using index |
+----+--------------------+---------+----------------+--------+----------------+----------------+---------+------+----------+-------------+

子查詢 type 列的值為 index_subquery,ref 列的值為 func。

這 2 列的值看起來挺唬人的,但實(shí)際上和示例 SQL 1 的 type = ref,ref = sakila.city.city_id 并沒有什么不一樣,無非是換了一身行頭而已。

我們先從源碼里看看 type = index_subquery 是怎么來的:

// sql/opt_explain.cc
bool Explain_join::explain_join_type(){
const join_type j_t = type == JT_UNKNOWN ? JT_ALL : type;
const char *str = join_type_str[j_t];
// 訪問方式是 eq_ref
if ((j_t == JT_EQ_REF ||
// 訪問方式是 ref
j_t == JT_REF ||
// 訪問方式是 ref_or_null
j_t == JT_REF_OR_NULL) &&
// 當(dāng)前 select 語句是子查詢
join->query_expression()->item) {
/*
For backward-compatibility, we have special presentation of "index
lookup used for in(subquery)": we do not show "ref/etc", but
"index_subquery/unique_subquery".
*/
// 如果這個(gè) if 判斷條件成立
// 就說明 IN 子查詢已經(jīng)轉(zhuǎn)換為【相關(guān)子查詢】了
if (join->query_expression()->item->engine_type() ==
Item_subselect::INDEXSUBQUERY_ENGINE)
str = (j_t == JT_EQ_REF)
? "unique_subquery"
: "index_subquery";
}

fmt->entry()->col_join_type.set_const(str);
return false;
}

上面代碼是 explain 結(jié)果中 type 列的顯示邏輯。

從代碼可以看到 IN 子查詢轉(zhuǎn)換為相關(guān)子查詢之后,type 列的顯示邏輯如下:

  • 表的訪問方式是eq_ref,type 列的值為 unique_subquery。
  • 表的訪問方式是ref 或 ref_or_null,type 列的值為 index_subquery。

由此,我們就揭開了 index_subquery 的神秘面紗,實(shí)際上它就是 ref 或 ref_no_null。

另外,從代碼的英文注釋中,我們可以看到,type 列之所以這么顯示是為了向后兼容。

接下來,我們再來看看 ref 列的顯示邏輯:

// sql/sql_select.h
class store_key {
......
virtual const char *name() const {
// Compatible with legacy behavior.
// where 條件字段是正常字段(另一個(gè)表的字段)
// 返回的是字段全名,即 db.table.field
if (item->type() == Item::FIELD_ITEM) {
return item->full_name();
} else {
return "func";
}
}
......
}

IN 子查詢轉(zhuǎn)換為相關(guān)子查詢之后,主查詢 where 條件的 city_id 字段和子查詢 select 子句的 city_id 字段會組成新條件(address.city_id = city.city_id),附加到子查詢 where 條件中。

新條件的 city.city_id 字段類型是 REF_ITEM,而不是 FIELD_ITEM,在調(diào)試控制臺執(zhí)行如下命令可以驗(yàn)證:

這里 REF_ITEM 是對 FIELD_ITEM 的引用,這是源碼中對包含子查詢的 IN 條件字段所做的優(yōu)化,我們在此不深入具體細(xì)節(jié)。

# 新條件 city.city_id 字段的表名
(lldb) print ((Item_field *)((Item_cache_int *)item->real_item())->get_example())->table_name
(const char *) $16 = "city"
# 新條件 city.city_id 字段的字段名
(lldb) print ((Item_field *)((Item_cache_int *)item->real_item())->get_example())->field_name
(const char *) $17 = "city_id"
# 新條件 city.city_id 的類型
(lldb) print item->type()
(Item::Type) $18 = REF_ITEM

所以,新條件類型是 REF_ITEM,命中了前面代碼中的 else 分支(return "func"),explain 結(jié)果的 ref 列就顯示為 func 了。

ref 列的值雖然顯示為 func,但是新條件 city.city_id 字段還是讀取的主查詢 city_id 字段值,只不過是中間隔了一層,其它并沒有什么特殊的。

圖片

厘清了兩種 SQL explain 結(jié)果 type、ref 列的不同之處,就可以開始介紹不相關(guān)子查詢轉(zhuǎn)換為相關(guān)子查詢的邏輯了。

因?yàn)樵诮榻B過程中會用到 optimizer trace,所以先來簡單了解下 optimizer trace 的相關(guān)知識點(diǎn)。

2、optimizer trace

通過 optimizer trace,我們可以了解到 MySQL 準(zhǔn)備階段、優(yōu)化階段、執(zhí)行階段的一些內(nèi)部細(xì)節(jié)。特別是可以了解 MySQL 選擇某個(gè)執(zhí)行計(jì)劃的決策依據(jù)。

optimizer trace 默認(rèn)為關(guān)閉狀態(tài),如果需要,可以通過執(zhí)行以下 SQL 開啟:

SET optimizer_trace = "enabled=on"

開啟了 optimizer trace,執(zhí)行 SQL 語句之后,可以通過以下 SQL 得到 optimizer trace 結(jié)果:

SELECT * FROM information_schema.OPTIMIZER_TRACE

OPTIMIZER_TRACE 表有 4 個(gè)字段:

  • QUERY:SQL 語句。
  • TRACE:json 格式的 optimizer trace 內(nèi)容,如果內(nèi)容長度超過系統(tǒng)變量 optimizer_trace_max_mem_size 的值就會被截?cái)?。該系統(tǒng)變量控制的是一條 SQL 的 optimizer trace 內(nèi)容長度,默認(rèn)值是 1048576(字節(jié))。
  • MISSING_BYTES_BEYOND_MAX_MEM_SIZE:如果 optimizer trace 內(nèi)容因超長被截?cái)啵@個(gè)字段記錄了被截?cái)嗟淖止?jié)數(shù)。
  • INSUFFICIENT_PRIVILEGES:如果用戶執(zhí)行 QUERY 字段中的 SQL 語句權(quán)限不夠,導(dǎo)致 TRACE 字段內(nèi)容為空,該字段會顯示為 1。

如果使用客戶端(如 Navicat),我們執(zhí)行一條 SQL,客戶端可能會額外執(zhí)行一些統(tǒng)計(jì) SQL。

因?yàn)槟J(rèn)配置只會保留最近一條 SQL 的 optimizer trace 內(nèi)容,使用客戶端有可能導(dǎo)致我們看不到自己的 SQL optimizer trace 內(nèi)容。

這種情況下,我們需要修改 2 個(gè)系統(tǒng)變量的值:

  • optimizer_trace_offset:從最近執(zhí)行的哪條 SQL 開始保存 optimizer trace 內(nèi)容,默認(rèn)值為 -1,表示從最近執(zhí)行的 1 條 SQL 開始保存 optimizer trace 內(nèi)容。
  • optimizer_trace_limit:保存多少條 optimizer trace 內(nèi)容,默認(rèn)值為 1。

圖片

3、IN 子查詢轉(zhuǎn)換

IN 子查詢有 3 大執(zhí)行策略:

  • 轉(zhuǎn)換為半連接,這是最優(yōu)先的執(zhí)行策略。
  • 子查詢物化。
  • 轉(zhuǎn)換為相關(guān)子查詢。

如果子查詢中存在像 group by 子句這樣的限制因素,或者因?yàn)槌杀締栴}不能轉(zhuǎn)換為半連接,那就要在物化和相關(guān)子查詢兩種策略中二選一了。

(1)要不要轉(zhuǎn)換?

還是以前面的 IN 子查詢 SQL 為例,我們通過 optimizer trace 來看看 MySQL 在物化和相關(guān)子查詢兩種策略中二選一的過程。

-- 為了保證 IN 子查詢不會轉(zhuǎn)換為半連接
-- 先把半連接優(yōu)化關(guān)閉
SET optimizer_switch="semijoin=off";

-- 開啟 optimizer trace
SET optimizer_trace = "enabled=on";

-- 執(zhí)行 select 語句
SELECT * FROM city
WHERE city_id < 100 AND city_id IN (
SELECT city_id FROM address
);

-- 獲取 select 語句的跟蹤信息
SELECT * FROM information_schema.OPTIMIZER_TRACE;

以下是 optimizer trace 中關(guān)于物化和相關(guān)子查詢兩種策略的決策依據(jù):

{
"execution_plan_for_potential_materialization": {
"subq_mat_decision": {
"parent_fanouts": [
{
"select#": 1,
"subq_attached_to_table": true,
"table": "`city`",
"fanout": 99,
"cacheable": true
}
],
"cost_to_create_and_fill_materialized_table": 123.849,
"cost_of_one_EXISTS": 0.349669,
"number_of_subquery_evaluations": 99,
"cost_of_materialization": 133.749,
"cost_of_EXISTS": 34.6172,
"chosen": false
}
}
}

chosen 字段值為 false?,表示 MySQL 沒有?使用物化方式執(zhí)行子查詢,原因是使用物化方式的成本(cost_of_materialization = 133.749?)比相關(guān)子查詢的成本(cost_of_EXISTS = 34.6172)更高。

知道了結(jié)果,我們再來看看物化和相關(guān)子查詢的成本是怎么計(jì)算的。

使用物化方式執(zhí)行子查詢的成本:

parent_fanouts.fanout = 99 表示預(yù)估的主查詢 city 表中滿足 city_id < 100 的記錄數(shù)量。

number_of_subquery_evaluations 表示子查詢的執(zhí)行次數(shù)?,因?yàn)閷τ谥鞑樵冎袧M足 city_id < 100 的每一條記錄,相關(guān)子查詢都要執(zhí)行一次,所以,這個(gè)字段值等于 parent_fanouts.fanout。

cost_to_create_and_fill_materialized_table 表示創(chuàng)建臨時(shí)表的成本,加上把子查詢中的所有記錄都寫入臨時(shí)表的成本。

cost_of_materialization 表示使用物化方式執(zhí)行 IN 子查詢的總成本,計(jì)算邏輯如下:cost_of_materialization = ?cost_to_create_and_fill_materialized_table?(123.849) + number_of_subquery_evaluations(99) * 0.1 = 133.749。

其中 0.1 是從主查詢中讀取一條記錄之后,拿到 city_id 字段值,去臨時(shí)表中查詢記錄的成本常數(shù),可以通過以下 SQL 獲取:

SELECT
cost_name, cost_value, default_value
FROM mysql.server_cost
WHERE cost_name = 'memory_temptable_row_cost'

+---------------------------+------------+---------------+
| cost_name | cost_value | default_value |
+---------------------------+------------+---------------+
| memory_temptable_row_cost | <null> | 0.1 |
+---------------------------+------------+---------------+

查詢 cost_name 等于 memory_temptable_row_cost 的成本常數(shù),因?yàn)槭褂玫氖莾?nèi)存臨時(shí)表。

如果子查詢使用的是磁盤臨時(shí)表,則需要查詢 cost_name 等于 disk_temptable_row_cost 的成本常數(shù)。

轉(zhuǎn)換為相關(guān)子查詢的執(zhí)行成本:cost_of_EXISTS = ?cost_of_one_EXISTS?(0.349669) * number_of_subquery_evaluations(99) = 34.6172。

cost_of_one_EXISTS 表示子查詢執(zhí)行一次的成本,number_of_subquery_evaluations 表示子查詢的執(zhí)行次數(shù)。

(2)怎么轉(zhuǎn)換?

還是以前面的示例 SQL 為例:

SELECT * FROM city
WHERE city_id < 100 AND city_id IN (
SELECT city_id FROM address
)

在查詢準(zhǔn)備階段,還沒有確定子查詢的執(zhí)行策略之前,就會把主查詢 where 條件中的 IN 條件字段和子查詢 select 子句中的字段組成新條件,并附加到子查詢的 where 條件中。

也就是把 city 表的 city_id 字段和 address 表的 city_id 字段組成新條件,附加到子查詢中,看起來就像是這樣的 select 語句:

SELECT * FROM city
WHERE city_id < 100 AND EXISTS (
SELECT city_id FROM address
WHERE city.city_id = address.city_id
)

那么問題來了,如果查詢優(yōu)化階段決定 IN 子查詢不轉(zhuǎn)換為相關(guān)子查詢,附加到子查詢 where 條件中的新條件怎么辦?

這個(gè)好辦,再刪掉就是了。

在構(gòu)造的時(shí)候,新條件會被打上標(biāo)記,表示這個(gè)條件是 IN 子查詢轉(zhuǎn)換為相關(guān)子查詢時(shí)新構(gòu)造的。

有了這個(gè)標(biāo)記,就能知道要?jiǎng)h除子查詢 where 條件中的那個(gè)條件了。

4、執(zhí)行流程

不管是 IN 子查詢轉(zhuǎn)換來的,還是我們純手工打造的相關(guān)子查詢,到了執(zhí)行階段,流程就一樣了。

還是以前面的示例 SQL 1 為例,來介紹相關(guān)子查詢的主要執(zhí)行流程:

SELECT * FROM city
WHERE city_id < 100 AND EXISTS (
SELECT city_id FROM address
WHERE city.city_id = address.city_id
)

步驟 1,主查詢從 city 表讀取一條記錄。

步驟 2,判斷主查詢記錄是否匹配 where 條件。

因?yàn)?nbsp;city_id < 100 在前,先判斷主查詢記錄是否滿足這個(gè)條件。

如果滿足,則執(zhí)行子查詢,否則,回到步驟 1。

假設(shè)主查詢讀取到 city 表的 city_id 字段值為 8,此時(shí),要執(zhí)行的子查詢就是這樣的了:

SELECT city_id FROM address
WHERE address.city_id = 8

如果執(zhí)行子查詢查到了記錄,說明主查詢記錄滿足 city_id < 100 和 EXISTS 子查詢兩個(gè)條件,把主查詢記錄返回給客戶端,否則,回到步驟 1。

重復(fù)執(zhí)行步驟 1 ~ 2,直到讀完主查詢 city 表中滿足 city_id < 100 的所有記錄,執(zhí)行流程結(jié)束。

通過 optimizer trace 也可以驗(yàn)證主查詢每讀取一條滿足 city_id < 100 的記錄,EXISTS 子查詢都要執(zhí)行一次,如下:

{
"join_execution": {
"select#": 1,
"steps": [
{
// 主查詢一共有 99 滿足 where 條件的記錄
// steps 中有 99 個(gè) subselect_execution
"subselect_execution": {
"select#": 2,
"steps": [
{
"join_execution": {
"select#": 2,
"steps": []
}
}
]
}
// 此處省略 98 個(gè) subselect_execution
// ......
}
]
}
}

以下是 optimizer trace 的部分內(nèi)容截圖,expanded_query 就是經(jīng)過 MySQL 展開處理之后的 select 語句,我做了一些簡化和處理,如下:

圖片

join_execution 的 steps 后面,99 items 就是 99 個(gè)折疊起來的 subselect_execution。

5、最佳實(shí)踐

MySQL 讀取主查詢的一條記錄之后,判斷記錄是否匹配 where 條件,是按照我們寫 SQL 時(shí)字段在 where 條件中出現(xiàn)的順序進(jìn)行判斷的。

由于判斷主查詢記錄是否匹配 IN 子查詢條件時(shí),需要執(zhí)行子查詢,成本比較高,所以,我們寫 SQL 的時(shí)候最好是把不包含子查詢的 where 條件放在前面,包含子查詢的 where 條件放在最后。

這個(gè)邏輯在《??MySQL 不相關(guān)子查詢怎么執(zhí)行???》 中有過詳細(xì)介紹,這里不再重復(fù)了。

6、總結(jié)

本文主要介紹了以下內(nèi)容:

  • 不相關(guān)子查詢轉(zhuǎn)換為相關(guān)子查詢之后,explain 結(jié)果中:
  • 子查詢 type 列的值 unique_subquery 是 eq_ref 的別名;index_subquery 是 ref 或 ref_or_null 的別名。
  • 子查詢 ref 列的值會顯示為 func,這是因?yàn)橹鞑樵?IN 條件字段和子查詢 select 子句字段組成的新條件中,IN 條件字段引用了主查詢表中的字段,而不是直接使用主查詢表中的字段。
  • 不相關(guān)子查詢,如果不能轉(zhuǎn)換為半連接,則會在物化和相關(guān)子查詢兩種策略中二選一。
  • 兩種策略二選一的依據(jù)是子查詢執(zhí)行成本,哪種執(zhí)行成本低就選擇哪種。通過 optimizer trace 可以看到兩種執(zhí)行策略的成本。
  • 簡單介紹了相關(guān)子查詢的執(zhí)行流程。

本文轉(zhuǎn)載自微信公眾號「一樹一溪」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系一樹一溪公眾號。

責(zé)任編輯:姜華 來源: 一樹一溪
相關(guān)推薦

2020-10-15 06:56:51

MySQL排序

2021-04-23 10:31:18

MySQLRole數(shù)據(jù)庫

2021-07-30 10:33:57

MySQL觸發(fā)器數(shù)據(jù)

2021-03-01 18:37:15

MySQL存儲數(shù)據(jù)

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2023-09-22 17:36:37

2018-06-07 13:17:12

契約測試單元測試API測試

2023-07-06 13:56:14

微軟Skype

2021-02-06 08:34:49

函數(shù)memoize文檔

2022-11-01 08:46:20

責(zé)任鏈模式對象

2022-08-08 08:25:21

Javajar 文件

2019-02-13 14:15:59

Linux版本Fedora

2018-11-29 09:13:47

CPU中斷控制器

2021-08-04 09:32:05

Typescript 技巧Partial

2023-05-15 08:38:58

模板方法模式

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2022-11-26 00:00:06

裝飾者模式Component

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2020-08-12 08:34:16

開發(fā)安全We
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

九九久久久久99精品| 欧美视频免费在线观看| 91麻豆精品秘密入口| 日韩精品乱码久久久久久| 日韩高清在线免费观看| 欧美亚洲动漫精品| 欧美在线观看黄| 蝌蚪视频在线播放| 捆绑紧缚一区二区三区视频| 久久99热精品| 日本高清黄色片| 粉嫩精品导航导航| 欧美亚洲动漫制服丝袜| 国产九色porny| 黄色片在线免费看| 福利91精品一区二区三区| 日韩男女性生活视频| 国产少妇在线观看| 日本精品黄色| 亚洲精品自拍第一页| 亚洲午夜精品一区| 忘忧草在线www成人影院| 欧美激情日韩| 亚洲男帅同性gay1069| 久草精品电影| 亚洲精品字幕在线观看| 日韩电影免费在线看| 国内精品久久久久久中文字幕| 免费成人深夜天涯网站| 粉嫩av一区二区| 日韩一区二区三区在线| 天天干天天草天天| 欧美粗大gay| 黑人精品xxx一区一二区| 国产香蕉一区二区三区| 9色在线视频| 久久久久99精品一区| 国产女主播一区二区| 精品人妻一区二区三区麻豆91| 蜜臀精品一区二区三区在线观看 | 中文字幕成人一区| 国产专区在线播放| 97se亚洲国产综合自在线观| www.久久草| 亚洲国产精品久久人人爱潘金莲| 久久99精品久久只有精品| 国产成人福利视频| 久久亚洲精品石原莉奈 | 97在线视频精品| 国产精品theporn动漫| 好吊一区二区三区| 久久久综合免费视频| 久久久久成人片免费观看蜜芽| 亚洲欧洲中文字幕| 久久视频免费观看| 欧美日韩中文字幕在线观看| 欧美黄免费看| 性日韩欧美在线视频| 国产又黄又粗又爽| 久久一二三四| 国产精品丝袜视频| 99在线观看精品视频| 国产成人一区在线| 91精品国产一区二区三区动漫| 国产福利资源在线| 国产成人免费在线| 精品一区久久久| 国产小视频在线观看| 亚洲国产精品成人综合| 国产91av视频在线观看| 黄色免费在线观看| 亚洲一区二区在线播放相泽 | 九九色在线视频| 亚洲一区二区中文在线| 精品久久一二三| 先锋欧美三级| 日韩一区二区三免费高清| 日韩高清一二三区| 亚州精品视频| 日韩中文字幕在线观看| 免费在线视频观看| 免费亚洲网站| 亚洲999一在线观看www| 日批视频免费播放| 欧美高清在线一区二区| 久久久久福利视频| 自由日本语热亚洲人| 欧美高清视频一二三区| 影音先锋黄色资源| 欧美日韩性在线观看| 久久国产精品久久久久久| 黄色片视频网站| 美女视频第一区二区三区免费观看网站| 亚洲综合色av| 男生女生差差差的视频在线观看| 亚洲欧洲成人精品av97| 免费 成 人 黄 色| 综合久久av| 精品亚洲va在线va天堂资源站| 三级黄色片在线观看| 99热在线精品观看| 成人在线视频网站| 暖暖视频在线免费观看| 亚洲美女精品一区| 日本一极黄色片| 日韩一级淫片| 丝袜美腿精品国产二区| 69成人免费视频| 国产不卡视频一区| 亚欧洲精品在线视频免费观看| 国产极品人妖在线观看| 欧美疯狂做受xxxx富婆| 李宗瑞91在线正在播放| 一区二区亚洲精品| 成人久久久久久| 狠狠色伊人亚洲综合网站l| 一区二区三区免费网站| 久久久久久蜜桃一区二区| 欧美黄色影院| 久久久久亚洲精品国产| 国产精品丝袜黑色高跟鞋| 久久人人97超碰com| 久草免费福利在线| 国产亚洲高清一区| 色偷偷噜噜噜亚洲男人的天堂| 欧美一级特黄视频| 成人久久18免费网站麻豆| av不卡在线免费观看| 最新日韩一区| 亚洲欧美一区二区三区在线| 色播视频在线播放| www.99精品| 僵尸世界大战2 在线播放| 欧美激情精品| 欧美成人中文字幕在线| 国产剧情精品在线| 中文字幕在线观看不卡视频| 高清一区在线观看| 精品盗摄女厕tp美女嘘嘘| 啪一啪鲁一鲁2019在线视频| 五月激情婷婷网| 精品成人av一区| av电影在线播放| 激情视频一区| 久久爱av电影| 新版的欧美在线视频| 亚洲精品自拍第一页| 国产高清中文字幕| 久久九九全国免费| 国产真人无码作爱视频免费| 国内精品久久久久久99蜜桃| 国产成人+综合亚洲+天堂| 青草久久伊人| 欧美四级电影在线观看| 国精产品视频一二二区| 国产一区福利在线| 国产日韩亚洲欧美在线| 久久久久高潮毛片免费全部播放| 久久人人97超碰精品888| 日韩在线观看视频一区| 欧美性69xxxx肥| 娇妻被老王脔到高潮失禁视频| 日本午夜精品一区二区三区电影 | 91视频国产精品| 在线午夜影院| 亚洲韩国青草视频| 黄色在线视频网址| 国产精品三级电影| 国产精品中文久久久久久| 在线看片一区| 欧美一区国产一区| 高清在线一区| 欧美第一淫aaasss性| 天堂在线一二区| 欧亚一区二区三区| 欧产日产国产v| 93久久精品日日躁夜夜躁欧美| 亚洲人成无码www久久久| 欧美电影免费播放| 国产精品视频入口| 色综合天天色| 欧美情侣性视频| 国产精品一二三区视频| 91精品国产高清一区二区三区蜜臀| 精品深夜av无码一区二区老年| 91麻豆免费观看| 亚洲欧美天堂在线| 亚洲美女少妇无套啪啪呻吟| 亚洲视频小说| 欧美成人午夜77777| 国产欧美日韩精品专区| 色老头在线观看| 一本大道久久加勒比香蕉| 精品人妻aV中文字幕乱码色欲 | 国产主播在线看| 婷婷综合在线| 欧美高清性xxxxhd| 狂野欧美xxxx韩国少妇| 国产精品96久久久久久| 色婷婷在线播放| 中文字幕日韩av电影| 色欲av永久无码精品无码蜜桃| 欧美日韩五月天| 天堂网av手机版| 亚洲自拍另类综合| 国产3级在线观看| 99热99精品| 91精品国产高清91久久久久久 | 99av国产精品欲麻豆| 一区不卡字幕| 国产精品一区二区99| 国产精品一区在线播放| 91福利精品在线观看| 18一19gay欧美视频网站| 二区三区四区高清视频在线观看| 亚洲欧美精品一区二区| 韩国av永久免费| 4438x亚洲最大成人网| 国产又粗又猛又爽又| 午夜一区二区三区视频| 欧美丰满艳妇bbwbbw| 国产精品的网站| 91精品国自产在线| 久久综合色一综合色88| 中文成人无字幕乱码精品区| 国产成人av影院| 青娱乐精品在线| 久久99精品国产.久久久久久| 日本男人操女人| 美女精品在线| 国产精品亚洲αv天堂无码| 亚洲国内精品| 可以在线看的av网站| 伊人影院久久| 很污的网站在线观看| 亚洲高清久久| 精品少妇在线视频| 18成人免费观看视频| 五月丁香综合缴情六月小说| 欧美性久久久| 欧美日韩一道本| 国产日韩欧美高清免费| 日本福利视频在线| 国产日韩精品视频一区二区三区| 国产成人无码a区在线观看视频| 亚洲国产一区二区精品专区| 日日摸日日碰夜夜爽无码| 136国产福利精品导航网址| 国产真人做爰毛片视频直播| 亚洲精品综合| 麻豆av免费在线| 日本欧美在线观看| 黄色一级片免费的| 国内久久精品视频| 可以看的av网址| 成人免费视频网站在线观看| 国产精品久久无码| 久久久99免费| 亚洲一级二级片| 夜夜精品浪潮av一区二区三区| 不卡的免费av| 日韩欧美亚洲综合| 中文字幕日韩第一页| 这里是久久伊人| 蜜桃91麻豆精品一二三区| 亚洲大胆人体av| 黑人与亚洲人色ⅹvideos| 最新的欧美黄色| 中文字幕在线播放网址| 97人人爽人人喊人人模波多| 玛雅亚洲电影| 成人日韩在线电影| 精品少妇3p| 亚洲人久久久| 欧美日韩国产成人精品| 国产亚洲综合视频| 久久国产麻豆精品| 中文字幕天堂av| 欧美激情一区二区在线| 农村妇女精品一区二区| 午夜精品久久久久影视| 这里只有精品999| 欧美变态凌虐bdsm| 户外极限露出调教在线视频| 欧美成人合集magnet| 欧亚av在线| 成人精品视频久久久久| 色婷婷综合久久久久久| www.-级毛片线天内射视视| 亚洲日韩视频| 色18美女社区| 91美女片黄在线观看91美女| 一区二区三区影视| 色综合中文综合网| 午夜久久久久久噜噜噜噜| 亚洲色图色老头| 欧美xxxx性xxxxx高清| 国产精品高潮视频| 精品国产导航| 国产精品一区在线免费观看| 日日骚欧美日韩| 日本美女视频网站| 综合久久久久久| 国产嫩bbwbbw高潮| 精品国产免费人成在线观看| av在线免费播放网站| 992tv在线成人免费观看| 国产95亚洲| 日韩中文字幕av在线| 亚洲精品视频啊美女在线直播| 一级黄色大片儿| 亚洲国产精华液网站w| 亚洲精品1区2区3区| 欧美一区2区视频在线观看| 福利小视频在线观看| 2019中文字幕在线观看| 国产成人aa在线观看网站站| 性欧美18一19内谢| 蜜桃av一区二区在线观看| 日韩一级视频在线观看| 午夜久久久影院| 黄色三级网站在线观看| 欧美成人午夜激情视频| 欧洲美女精品免费观看视频| 日本一区免费看| 久久久噜噜噜| av在线网站观看| 五月激情综合婷婷| 理论片中文字幕| 欧美疯狂性受xxxxx另类| 精品国产亚洲一区二区三区在线 | 永久免费观看片现看| 91黄色免费版| 久久经典视频| 日本精品免费一区二区三区| 亚洲bt欧美bt精品777| 国产特级黄色大片| 99久久精品费精品国产一区二区| 日本熟妇毛茸茸丰满| 欧美精品一区二区三区蜜臀| 爱看av在线入口| 精品国产乱码久久久久久88av | 污污网站在线免费观看| 992tv成人免费影院| 欧美毛片免费观看| 99久久久无码国产精品6| 久久亚洲春色中文字幕久久久| 成人免费视频毛片| 亚洲精品一区二区网址| 亚洲wwww| 亚洲图片欧洲图片日韩av| 韩国av一区二区| 欧美精品成人久久| 亚洲国产美女久久久久| 免费成人动漫| 亚洲图片都市激情| 国产麻豆视频精品| 国产一级做a爱免费视频| 亚洲国产成人精品女人久久久| 91色在线看| 日本在线视频一区| 久久 天天综合| 国产无遮挡又黄又爽| 日韩av网站大全| 欧美va视频| 男女裸体影院高潮| 91在线精品秘密一区二区| 国产午夜无码视频在线观看 | 欧美日韩精品免费在线观看视频| 日韩成人午夜电影| 99视频只有精品| 亚洲精品一区二区三区精华液| 免费h在线看| 亚洲午夜在线观看| 成人免费视频一区| 最近中文在线观看| 欧美肥臀大乳一区二区免费视频| 激情小说一区| 国产精品区在线| 亚洲高清久久久| 在线激情网站| 国产精品我不卡| 蜜臀av性久久久久蜜臀aⅴ四虎| 1024手机在线视频| 亚洲日本aⅴ片在线观看香蕉| 91成人精品观看| 日本一区二区黄色| 亚洲女子a中天字幕| 日本ー区在线视频| 亚洲最大成人免费视频| 亚洲综合不卡| 青青草激情视频| 一区二区三区回区在观看免费视频| 欧美影院视频| 国产视频一区二区三区在线播放 | 国产精品色呦呦| 日韩一级片免费观看| 国产日韩精品在线| 国产婷婷精品| 欧美激情一区二区视频|