青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

DB2 中 MQT 的匹配原理及使用技巧

Posted on 2010-04-26 23:25 Prayer 閱讀(1274) 評論(6)  編輯 收藏 引用 所屬分類: DB2

  簡介

  MQT(Materialized Query Table,物化查詢表) 物化了涉及一個或多個表或昵稱的查詢的預先計算結果。而后續的查詢可以通過全部或部分匹配 MQT,并由 DB2 來補償剩余的查詢功能,從而達到提高查詢性能的目的。本文將會介紹 DB2 中 MQT 匹配的基本原理,并基于此指出如何設計 MQT 從而能使得查詢獲得更高的匹配率從而提高查詢效率。

  MQT 匹配原理

  MQT 在 OLAP 場景下能夠有效提高復雜查詢響應時間,尤其是有下面幾類數據操作需求的查詢:

  在一個或多個維度上聚合數據。

  在多個表之間連接數據。

  數據來自于一個常見的數據訪問子集—也就是該子集會被頻繁訪問,MQT 能夠避免重復計算。

  MQT 對應用程序是完全透明的。MQT 的相關信息已經被整合進 DB2 SQL 編譯器中,它們會判斷是否 MQT 應該被用來響應一個完整查詢或者查詢的一部分。因此,用戶可以在不改變應用程序代碼的情況下,創建和刪除 MQTs,就和創建和刪除索引而不需要更改應用程序一樣。

  而如何做到上面的透明性,這是由 DB2 SQL 編譯器的 MQT 匹配算法來完成。如果我們把自己作為 MQT 匹配算法的作者,最容易想到的就是 MQT 需要滿足以下條件才能夠被匹配:MQT 中包含查詢需要的所有行 (Record);MQT 中包含查詢需要的所有列 (Column);MQT 中行的冗余度與查詢結果一致。或者通過某種程度的補償能夠達到上述 3 個條件,那么 MQT 才有可能匹配對應查詢。在 DB2 中也是遵循上述基本原理來進行匹配。其大致步驟如下:1) 在查詢重寫 (Rewrite) 階段,DB2 編譯器會針對目前所有可能被匹配的 MQT 進行分析,并選擇一個最優的 MQT 匹配執行方案和不用 MQT 的執行方案。2) 在查詢優化 (Optimizer) 階段,會計算上述兩種方案的成本,并選擇成本最優的方案作為最終執行方案。需要注意的一點是在第一步中選擇最優 MQT 匹配方案是一種啟發式的選擇 (rule/heuristic based),并沒有真正計算成本。而且在這個過程中,可能匹配的 MQT 數目越多,需要的匹配過程越復雜,對應的編譯時間越長。所以說并不是 MQT 越多越好,一方面 MQT 會占用存儲空間,同時會增加編譯時間。用戶需要針對性地創建 MQT,保證其能夠真正帶來性能上的提升。而匹配的具體算法就不在這里詳細闡述。如果讀者有興趣,可以在參考資源 2 中找到具體細節。

  根據上面介紹的原理,以下 6 種查詢可以利用 MQT 來提高性能。本文將針對每種查詢舉例加以介紹:

  MQT 能夠精確匹配查詢;

  查詢結果集是 MQT 的子集;

  查詢中連接的表數目多于 MQT;

  查詢中連接的表是 MQT 中表的子集,需滿足引用完整性 (Reference Integrity, RI);

  查詢中包含 MQT 中不存在的列,需滿足功能依賴;

  查詢對應的聚集級別 (aggregation level) 高于 MQT。

  為了對上面的 6 種情況進行詳細介紹,先創建一些示例表以方便通過實例來闡述這些原理。如清單 1 所示,表 Product 和 Customer 是維表 (dimension table),且分別定義了唯一鍵;表 Sales 是事實表 (fact table),它通過 PROD_ID 和 CUST_ID 的外鍵約束來保證引用完整性。至于表 Product 上定義的函數依賴 (Functional Dependency),我們將在后面詳細討論。另外,在實驗的過程中人為的設置了基本表和 MQT 表的統計信息,使得編譯器在選擇查詢計劃總認為使用 MQT 的代價低。這并不影響 MQT 匹配的過程,而且簡化了討論。

清單 1. 創建示例中的表

 CREATE TABLE MQTSCH.PRODUCT(PROD_ID INT NOT NULL UNIQUE, 
 PROD_DESC VARCHAR(64), 
 CAT_ID INT NOT NULL, CAT_DESC VARCHAR(64), 
 GROUP_ID INT NOT NULL, GROUP_DESC VARCHAR(64), 
 CONSTRAINT FD1 CHECK 
 (CAT_DESC DETERMINED BY CAT_ID) 
 NOT ENFORCED ENABLE QUERY OPTIMIZATION, 
 CONSTRAINT FD2 CHECK 
 (GROUP_ID DETERMINED BY CAT_ID) 
 NOT ENFORCED ENABLE QUERY OPTIMIZATION 
 ); 
 
 CREATE TABLE MQTSCH.CUSTOMER(CUST_ID INT NOT NULL UNIQUE, 
 CUST_NAME VARCHAR(50), 
 CUST_ADDRESS VARCHAR(100)); 
 
 CREATE TABLE MQTSCH.SALES(PROD_ID INT NOT NULL REFERENCES MQTSCH.PRODUCT(PROD_ID), 
 CUST_ID INT NOT NULL REFERENCES MQTSCH.CUSTOMER(CUST_ID), 
 SALE_DATE DATE NOT NULL, 
 AMOUNT DECIMAL(9,2) NOT NULL); 
 
 runstats on table MQTSCH.CUSTOMER; 
 runstats on table MQTSCH.PRODUCT; 
 runstats on table MQTSCH.SALES; 
 update syscat.tables set card=20 where tabname='CUSTOMER'; 
 update syscat.tables set card=200 where tabname='PRODUCT'; 
 update syscat.tables set card=2000 where tabname='SALES'; 
 
 set current refresh age=any; 

  MQT 能夠精確匹配查詢

  這種情況是最容易理解的。當 MQT 能夠精確匹配查詢時,通常情況下,從 MQT 中獲取數據的性能會優于執行相應查詢,故選擇 MQT 的執行方案通常會勝出。清單 2 中給出一個示例。其中 MQT SALES_PROD 基于外鍵連接事實表 Sales 與維表 Product。而查詢則是同樣的 Join 操作。這時,MQT 能匹配這個查詢。在清單 2 中可以看到 MQT 和查詢的詳細內容,并且打印出的執行計劃和拓展診斷信息明確的顯示了 SALES_PROD 在查詢匹配時被利用了。

清單 2. 精確的 MQT 匹配

 --MQT definition: join for SALES and PRODUCT 
 CREATE TABLE MQTSCH.SALES_PROD AS 
 (SELECT P.PROD_ID, PROD_DESC, AMOUNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID) 
 DATA INITIALLY DEFERRED REFRESH DEFERRED; 
 
 refresh table MQTSCH.SALES_PROD; 
 
 --artifical statistics 
 runstats on table MQTSCH.SALES_PROD; 
 update syscat.tables set card=10 where tabname='SALES_PROD'; 
 
 --collect the explain information 
 DELETE FROM EXPLAIN_INSTANCE; 
 explain plan for SELECT P.PROD_ID, PROD_DESC, AMOUNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID; 
 
 !db2exfmt -1 -d mqtdb -o join.plan; 

  下面是 join.plan 打印出的執行計劃和診斷信息:

 Access Plan: 
----------- 
    Total Cost:       10.3414 
    Query Degree:      1 
 
   Rows 
   RETURN 
   (  1) 
   Cost 
    I/O 
    | 
    10 
   TBSCAN 
   (  2) 
   10.3414 
    1 
    | 
    10 
 TABLE: MQTSCH 
  SALES_PROD 
    Q1 
 
 
 Extended Diagnostic Information: 
 -------------------------------- 
 
 Diagnostic Identifier: 1 
 Diagnostic Details: EXP0148W The following MQT or statistical view was 
 considered in query matching: "MQTSCH ". 
 "SALES_PROD". 
 Diagnostic Identifier: 2 
 Diagnostic Details: EXP0149W The following MQT was used (from those 
 considered) in query matching: "MQTSCH ". 
 "SALES_PROD". 

  查詢結果集是 MQT 的子集

  這種情況也很容易理解。當查詢結果集是 MQT 的子集時,這意味著查詢需要的行與列在 MQT 中都能找到,而 DB2 只需要在對應 MQT 上執行剩余的謂詞 (predicate) 及計算 (head expression) 即可。如圖 2 所示,這種 MQT 只需要被計算一次就可以被多次重用。清單 3 則給出了該場景的一個具體例子。

圖 1. 查詢結果集是 MQT 子集示意圖
DB2 中 MQT 的匹配原理及使用技巧

  查看原圖(大圖)

清單 3. 查詢結果集是 MQT 子集匹配

 --MQT definition: join for SALES and PRODUCT 
 CREATE TABLE MQTSCH.SALES_PROD AS 
 (SELECT P.PROD_ID, PROD_DESC, AMOUNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID) 
 DATA INITIALLY DEFERRED REFRESH DEFERRED; 
 
 refresh table MQTSCH.SALES_PROD; 
 
 --artifical statistics 
 runstats on table MQTSCH.SALES_PROD; 
 update syscat.tables set card=10 where tabname='SALES_PROD'; 
 
 --collect the explain information 
 DELETE FROM EXPLAIN_INSTANCE; 
 explain plan for SELECT P.PROD_ID, PROD_DESC, AMOUNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID and AMOUNT > 10000; 
 
 !db2exfmt -1 -d mqtdb -o joinsub.plan; 

  下面是 join_sub.plan 打印出的執行計劃和診斷信息。有一點需要注意的是清單 2 與清單 3 中的 TBSCAN 并不完全相同。清單 3 中的 TBSCAN 包含謂詞 (10000 < Q1.AMOUNT)。

 Access Plan: 
 ----------- 
    Total Cost:       10.5194 
    Query Degree:      1 
 
   Rows 
   RETURN 
   (  1) 
   Cost 
    I/O 
    | 
   3.33333 
   TBSCAN 
   (  2) 
   10.5194 
    1 
    | 
    10 
 TABLE: MQTSCH 
  SALES_PROD 
    Q1 
 
 
 Extended Diagnostic Information: 
 -------------------------------- 
 
 Diagnostic Identifier: 1 
 Diagnostic Details: EXP0148W The following MQT or statistical view was 
 considered in query matching: "MQTSCH ". 
 "SALES_PROD". 
 Diagnostic Identifier: 2 
 Diagnostic Details: EXP0149W The following MQT was used (from those 
 considered) in query matching: "MQTSCH ". 
 "SALES_PROD". 

  查詢中連接的表數目多于 MQT

  根據前面介紹的 MQT 匹配原理,這種情況成立的前提是 MQT 完成所有連接后得到的結果集需要是查詢中對應表完成連接后結果集的超集。如果 MQT 包含查詢中沒有的謂詞并且過濾掉一部分結果集,則該 MQT 無法進行匹配。

圖 2. 查詢中連接的表數目多于 MQT 匹配示意圖
DB2 中 MQT 的匹配原理及使用技巧

  查看原圖(大圖)

清單 4. 查詢中連接的表數目多于 MQT 匹配

 --MQT definition: join for SALES and PRODUCT 
 CREATE TABLE MQTSCH.SALES_PROD AS 
 (SELECT P.PROD_ID, PROD_DESC, AMOUNT, CUST_ID 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID) 
 DATA INITIALLY DEFERRED REFRESH DEFERRED; 
 
 refresh table MQTSCH.SALES_PROD; 
 
 --artifical statistics 
 runstats on table MQTSCH.SALES_PROD; 
 update syscat.tables set card=10 where tabname='SALES_PROD'; 
 
 --collect the explain information 
 DELETE FROM EXPLAIN_INSTANCE; 
 explain plan for SELECT P.PROD_ID, PROD_DESC, AMOUNT, C.CUST_ID, CUST_NAME 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S, MQTSCH.CUSTOMER C 
 WHERE P.PROD_ID = S.PROD_ID 
 AND S.CUST_ID = C.CUST_ID; 
 
 !db2exfmt -1 -d mqtdb -o join_rejoin.plan; 

  下面是 join_rejoin.plan 打印出的執行計劃和診斷信息:

 Access Plan: 
 ----------- 
    Total Cost:       18.8629 
    Query Degree:      1 
 
        Rows 
       RETURN 
       (  1) 
        Cost 
        I/O 
        | 
        20 
       ^NLJOIN 
       (  2) 
       18.8629 
         2 
     /------+-------\ 
    1         20 
   TBSCAN       FETCH 
   (  3)       (  4) 
   9.72148      36.0967 
    1         4 
    |       /---+----\ 
    1      20      20 
 TABLE: MQTSCH   IXSCAN  TABLE: MQTSCH 
  SALES_PROD   (  5)   CUSTOMER 
    Q2     35.3323    Q1 
           4 
          | 
          20 
       INDEX: SYSIBM 
      SQL100124231518010 
          Q1 
 
 
 Extended Diagnostic Information: 
 -------------------------------- 
 
 Diagnostic Identifier: 1 
 Diagnostic Details: EXP0022W Index has no statistics. The index 
 "SYSIBM "."SQL100124231518010" has not had 
 runstats run on it. This can lead to poor 
 cardinality and predicate filtering estimates. 
 Diagnostic Identifier: 2 
 Diagnostic Details: EXP0148W The following MQT or statistical view was 
 considered in query matching: "MQTSCH ". 
 "SALES_PROD". 
 Diagnostic Identifier: 3 
 Diagnostic Details: EXP0149W The following MQT was used (from those 
 considered) in query matching: "MQTSCH ". 
 "SALES_PROD". 

  查詢中連接的表是 MQT 中的子集,需滿足 RI

  前面提到,MQT 匹配的前提是 MQT 僅包含且正好包含查詢所需要的數據行。因此,如果一個 MQT 中連接 (Join) 的表多于查詢中的表,一般不能用這個 MQT 來匹配,因為額外的 Join 操作會影響 MQT 所包含的行及對應的冗余度。然而,如果額外的 Join 操作是基于 RI(引用完整性)的,那么它不會增加或刪除任何行,編譯器能夠利用這個事實在上述情況中匹配 MQT。這種基于 RI 的 Join 操作在事實表和維表之間是很常見的。

  通過例子來說明。如圖 4 所示,SALES_PROD_CUST 這個 MQT 基于外鍵連接了事實表 Sales 與兩個維表 Product 和 Customer。而查詢則是在 Sales 和 Product 的 Join 操作。這時,MQT 能匹配這個查詢。 在清單 5 中可以看到 MQT 和查詢的詳細內容,并且打印出的執行計劃和拓展診斷信息明確的顯示了 SALES_PROD_CUST 在查詢匹配時被利用了。

圖 3. 含有額外 RI-Join 時的 MQT 匹配示意圖
DB2 中 MQT 的匹配原理及使用技巧

  查看原圖(大圖)

清單 5. 含有額外 RI-Join 時的 MQT 匹配

 --MQT definition: with extra RI-Joins 
 CREATE TABLE MQTSCH.SALES_PROD_CUST AS 
 (SELECT P.PROD_ID, CAT_DESC, AMOUNT, C.CUST_ID, CUST_NAME 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S, MQTSCH.CUSTOMER C 
 WHERE P.PROD_ID = S.PROD_ID 
 AND S.CUST_ID = C.CUST_ID ) 
 DATA INITIALLY DEFERRED REFRESH DEFERRED; 
 
 refresh table MQTSCH.SALES_PROD_CUST; 
 
 --artifical statistics 
 runstats on table MQTSCH.SALES_PROD_CUST; 
 update syscat.tables set card=10 where tabname='SALES_PROD_CUST'; 
 
 --collect the explain information 
 DELETE FROM EXPLAIN_INSTANCE; 
 explain plan for SELECT P.PROD_ID, CAT_DESC, AMOUNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID; 
 
 !db2exfmt -1 -d mqtdb -o join_redud.plan; 

  下面是 join_redun.plan 打印出的執行計劃和診斷信息:

Access Plan: 
----------- 
    Total Cost:       10.3414 
    Query Degree:      1 
 
   Rows 
   RETURN 
   (  1) 
   Cost 
    I/O 
    | 
    10 
   TBSCAN 
   (  2) 
   10.3414 
    1 
    | 
    10 
 TABLE: MQTSCH 
 SALES_PROD_CUST 
    Q1 
 
 
 Extended Diagnostic Information: 
 -------------------------------- 
 
 Diagnostic Identifier: 1 
 Diagnostic Details: EXP0148W The following MQT or statistical view was 
 considered in query matching: "MQTSCH ". 
 "SALES_PROD_CUST". 
 Diagnostic Identifier: 2 
 Diagnostic Details: EXP0149W The following MQT was used (from those 
 considered) in query matching: "MQTSCH ". 
 "SALES_PROD_CUST". 

  查詢中包含 MQT 中不存在的列,需滿足功能依賴

  在開始介紹接下來的 MQT 匹配原理之前,有必要先簡單介紹一下功能依賴 (Functional Dependency) 這個概念。Y 功能依賴于 X,是指 Y 的值由 X 決定,即每個 X 的值精確的對應著一個 Y 的值,記作 X -> Y。

  根據定義,關系表上的所有列都功能依賴于主鍵或唯一鍵。例如,清單 1 中 Product 表,PROD_ID ->CAT_ID。對于非鍵列之間的功能依賴,DB2 通過定義一個參考約束 (informational constraint) 來實現。如清單 1 中在 Product 表上 FD1 和 FD2,分別定義了 CAT_ID -> CAT_DESC 和 CAT_ID -> GROUP_ID 這兩個函數依賴。在參考約束定義中:

  關鍵字 DETERMETED BY 準確地表達了函數依賴的含義;

  NOT ENFORCED 表示在執行增刪改時 DB2 并不驗證數據來保證約束的完整性;

  ENABLE QUERY OPTIMIZATION 告訴編譯器可以利用這個函數依賴來重寫和優化查詢。

  由于 DB2 并不強制函數依賴的這種約束的完整性,根據這個函數依賴優化的查詢結果可能是錯誤的,因此,需要注意函數依賴的定義和維護。

  繼續 MQT 匹配的討論。我們知道,MQT 匹配時,要求查詢中需要的列都能從 MQT 中找到。那么如果查詢中包含 MQT 不存在的列呢?函數依賴讓這種匹配也變成可能。DB2 根據這些函數依賴重寫查詢,通過 MQT 和基本表的 re-join 來獲得 MQT 缺少的列。

  在清單 6 的例子中,MQT SALES_BY_CAT 的定義包含列 CAT_ID,統計每類產品的銷售總量,然而查詢卻希望獲得 CAT_DESC 和銷售總量,而 CAT_DESC 不在 MQT 中。如果沒有函數依賴,這個 MQT 是不能匹配的。而正是 Product 上的函數依賴 CAT_ID -> CAT_DESC 讓這個 MQT 的匹配變成可能。

  拓展診斷信息 (Extended Diagnostic Information) 段揭示了編譯器的整個處理過程:診斷信息 1 中 EXP0073W 說明由于查詢中包含 MQT 沒有的列,這個 MQT 不能匹配;診斷 3 中 EXP0149W 表示當編譯器收集到函數依賴后,用 MQT 匹配了這個查詢。優化后的語句和執行計劃一致的顯示 MQT 的匹配以及 re-join 操作的生成。

  由于 CAT_ID 不是具有唯一性的鍵,優化后的語句中利用 DISTINCT 來去除重復,對應了查詢計劃的 SORT 操作。一般情況下,這個 DISTINCT 是作用在維表上,開銷很小。

清單 6. 含有額外 RI-Join 時的 MQT 匹配

 --MQT missing columns, with FD 
 CREATE TABLE MQTSCH.SALES_BY_CAT AS 
 (SELECT CAT_ID, SUM(AMOUNT) AS TOTAL, COUNT(*) AS CNT 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID 
 GROUP BY CAT_ID ) 
 DATA INITIALLY DEFERRED REFRESH IMMEDIATE; 
 
 refresh table MQTSCH.SALES_BY_CAT; 
 runstats on table MQTSCH.SALES_BY_CAT; 
 update syscat.tables set card=10 where tabname='SALES_BY_CAT'; 
 
 --collect the explain information 
 DELETE FROM EXPLAIN_INSTANCE; 
 explain plan for SELECT CAT_DESC, SUM(AMOUNT) 
 FROM MQTSCH.PRODUCT P, MQTSCH.SALES S 
 WHERE P.PROD_ID = S.PROD_ID 
 GROUP BY CAT_ID, CAT_DESC; 
 
 !db2exfmt -1 -d mqtdb -o fd.plan; 

  下面是 fd.plan 打印出的執行計劃和診斷信息:

 Optimized Statement: 
 ------------------- 
 SELECT Q3.CAT_DESC AS "CAT_DESC", Q1.TOTAL 
 FROM MQTSCH.SALES_BY_CATAS Q1, 
 (SELECT DISTINCTQ2.CAT_DESC, Q2.CAT_ID 
 FROM MQTSCH.PRODUCT AS Q2) AS Q3 
 WHERE (Q1.CAT_ID = Q3.CAT_ID) 
 
 Access Plan: 
 ----------- 
    Total Cost:       98.6553 
    Query Degree:      1 
 
      Rows 
      RETURN 
      (  1) 
      Cost 
       I/O 
       | 
       0.4 
      HSJOIN 
      (  2) 
      98.6553 
       10 
     /---+----\ 
    10      1 
   TBSCAN    TBSCAN 
   (  3)    (  4) 
   74.9814   23.5881 
    9      1 
    |      | 
    10      1 
 TABLE: MQTSCH   SORT 
 SALES_BY_CAT  (  5) 
    Q1     23.5366 
           1 
          | 
          200 
         TBSCAN 
         (  6) 
         23.4286 
           1 
          | 
          200 
       TABLE: MQTSCH 
         PRODUCT 
          Q2 
 
 
 Extended Diagnostic Information: 
 -------------------------------- 
 
 Diagnostic Identifier: 1 
 Diagnostic Details: EXP0073W The following MQT or statistical view was 
 not eligible because one or more data filtering 
 predicates from the query could not be matched with 
 the MQT: "MQTSCH "."SALES_BY_CAT". 
 Diagnostic Identifier: 2 
 Diagnostic Details: EXP0148W The following MQT or statistical view was 
 considered in query matching: "MQTSCH ". 
 "SALES_BY_CAT". 
 Diagnostic Identifier: 3 
 Diagnostic Details: EXP0149W The following MQT was used (from those 
 considered) in query matching: "MQTSCH ". 
 "SALES_BY_CAT". 

    >>更多交流,請到 ChinaUnix【DB2論壇】:http://bbs2.chinaunix.net/forum-22-1.html

Feedback

# re: DB2 中 MQT 的匹配原理及使用技巧  回復  更多評論   

2010-06-12 00:17 by DorotheaLevine34
I received my first <a href="http://lowest-rate-loans.com/topics/business-loans">http://lowest-rate-loans.com</a> when I was 25 and it supported me a lot. But, I require the short term loan as well.

# re: DB2 中 MQT 的匹配原理及使用技巧  回復  更多評論   

2010-06-12 22:42 by buy essay
Scociety apprize your text! To buy essays or custom essay just about this good post will be a huge basis of information!

# re: DB2 中 MQT 的匹配原理及使用技巧  回復  更多評論   

2010-06-18 02:24 by essay writing
Left you beautiful sunshine on my blog, hope this would aid students. What companies should help scholars in writing? We could propose to purchase the essay papers.
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区久久久| 免费人成网站在线观看欧美高清| 久久午夜国产精品| 亚洲日本在线视频观看| 久久精品亚洲一区二区| 亚洲欧美另类中文字幕| 亚洲天堂久久| 久久久视频精品| 一本久道久久综合婷婷鲸鱼| 欧美激情一区二区三级高清视频| 看欧美日韩国产| 欧美h视频在线| 国产精品一区二区三区观看| 久久精品成人一区二区三区蜜臀| 午夜精品久久久久| 久久精品亚洲一区二区| 欧美大片在线看免费观看| 亚洲精品韩国| 亚洲影院免费| 久久这里有精品视频| 欧美成人精品在线观看| 久久亚洲综合色一区二区三区| 久久gogo国模裸体人体| 噜噜噜91成人网| 99视频精品免费观看| 亚洲欧美另类久久久精品2019| 久久精品成人一区二区三区蜜臀| 欧美激情黄色片| 国产精品性做久久久久久| **性色生活片久久毛片| 99在线观看免费视频精品观看| 欧美影院午夜播放| 亚洲卡通欧美制服中文| 久久成人在线| 欧美色图麻豆| 亚洲电影免费观看高清完整版在线 | 亚洲精品乱码久久久久久日本蜜臀| 一级日韩一区在线观看| 久久久久国产成人精品亚洲午夜| 亚洲人被黑人高潮完整版| 欧美一区二区三区男人的天堂| 欧美精品18+| 狠狠综合久久| 午夜精品99久久免费| 亚洲国产成人精品久久| 欧美专区一区二区三区| 国产精品久久久久久久久久三级| 亚洲国产精品精华液网站| 久久久久九九九九| 欧美日韩另类丝袜其他| 午夜精品视频网站| 欧美成人一区在线| 午夜久久资源| 欧美日韩色一区| 狠狠色综合网| 亚洲摸下面视频| 亚洲区第一页| 美女国内精品自产拍在线播放| 国产日韩欧美在线视频观看| 亚洲视频免费看| 91久久视频| 女同一区二区| 欧美成人资源| 在线亚洲欧美视频| 欧美高清在线精品一区| 香蕉久久夜色精品国产使用方法| 欧美日韩视频免费播放| 亚洲美女中文字幕| 亚洲电影第三页| 你懂的国产精品永久在线| 亚洲国产精品久久久久久女王| 久久久精品日韩| 欧美一区二区三区视频在线观看| 国产精品亚洲一区| 欧美在线免费观看亚洲| 欧美一级在线亚洲天堂| 国外成人免费视频| 鲁大师成人一区二区三区| 久久久久久午夜| 亚洲国产精品va在线观看黑人 | 亚洲在线视频观看| 一区二区三区四区五区精品| 国产精品久久久久久久午夜| 午夜在线成人av| 欧美伊久线香蕉线新在线| 极品少妇一区二区| 亚洲激情另类| 国产精品高潮呻吟久久av黑人| 欧美一二三区在线观看| 久久精品99国产精品酒店日本| 亚洲黄色av一区| 9i看片成人免费高清| 国产日韩专区在线| 欧美激情国产日韩| 欧美性大战久久久久久久| 久久精品免视看| 欧美激情bt| 欧美影院在线| 欧美国产一区二区在线观看 | 一区二区三区在线视频免费观看| 欧美黄色网络| 国产精品久久毛片a| 麻豆久久婷婷| 国产精品久久999| 免费久久99精品国产| 欧美日韩精品免费| 久久久www| 欧美日韩一级黄| 久久综合精品一区| 欧美系列电影免费观看| 麻豆精品传媒视频| 国产精品三上| 91久久精品久久国产性色也91| 国产欧美综合一区二区三区| 亚洲国产精品尤物yw在线观看| 国产日韩在线看片| 一本色道久久综合狠狠躁篇怎么玩 | 亚洲激情视频网站| 亚洲午夜精品一区二区| 亚洲国产精品123| 欧美一区二区三区免费看| 在线中文字幕一区| 老司机精品福利视频| 欧美一区二区视频免费观看| 欧美精品一线| 欧美国产一区视频在线观看| 国产一区二区欧美| 亚洲男人av电影| 亚洲欧美日韩国产一区| 欧美激情1区2区| 亚洲丰满少妇videoshd| 在线观看不卡av| 久久精品视频在线看| 欧美在线观看你懂的| 国产精品久线观看视频| 夜夜嗨av一区二区三区免费区| 亚洲精品中文在线| 免播放器亚洲一区| 欧美韩国日本一区| 亚洲国产精品电影| 久久免费观看视频| 免费精品视频| 亚洲精美视频| 欧美成人免费一级人片100| 嫩草国产精品入口| 亚洲高清视频一区二区| 猛男gaygay欧美视频| 欧美a一区二区| 亚洲精品乱码久久久久久黑人| 欧美大片在线观看一区| 亚洲大片在线| 99在线观看免费视频精品观看| 欧美三级不卡| 亚洲性av在线| 久久久久国产一区二区三区四区| 国产一级揄自揄精品视频| 久久精品首页| 亚洲激情视频在线| 日韩西西人体444www| 欧美视频在线观看| 欧美影院午夜播放| 欧美激情2020午夜免费观看| 亚洲人成网站777色婷婷| 欧美日韩另类在线| 香蕉久久夜色精品国产使用方法| 欧美成人福利视频| 在线亚洲精品| 国产一区在线播放| 欧美激情欧美狂野欧美精品| 亚洲视频第一页| 美女主播视频一区| 亚洲视频专区在线| 黄色成人av网站| 欧美日韩精品不卡| 久久精品国产亚洲a| 亚洲精品午夜| 久久米奇亚洲| 亚洲欧美成aⅴ人在线观看| 狠狠色综合日日| 欧美性大战xxxxx久久久| 校园春色国产精品| 亚洲国产高清一区二区三区| 亚洲欧美日韩国产成人| 欧美不卡激情三级在线观看| 亚洲一区二区三区免费观看| 国产一区二区三区自拍| 蜜桃久久av| 午夜精品久久99蜜桃的功能介绍| 欧美激情一区二区三区蜜桃视频 | 亚洲一区免费看| 欧美成熟视频| 久久国产免费看| 一区二区三区回区在观看免费视频| 国产欧美日韩另类一区| 欧美激情成人在线| 久久全国免费视频| 亚洲免费视频在线观看| 亚洲乱码国产乱码精品精可以看 | 奶水喷射视频一区| 欧美一区二区三区喷汁尤物|