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

剖析 sharding-jdbc 如何實(shí)現(xiàn)分頁查詢

開發(fā)
本文從日常使用的角度出發(fā)來剖析一下sharding-jdbc底層是如何實(shí)現(xiàn)分頁查詢的,希望對你有幫助。

在之前的文章中筆者簡單的介紹了sharding-jdbc的使用,而本文從日常使用的角度出發(fā)來剖析一下sharding-jdbc底層是如何實(shí)現(xiàn)分頁查詢的。

前置依賴引入

之前的文章已經(jīng)介紹過sharding-jdbc底層會通過重寫數(shù)據(jù)源對應(yīng)的prepareStament完成分表查詢邏輯,而分頁插件則是攔截SQL語句實(shí)現(xiàn)分頁查詢,所以使用sharding-jdbc進(jìn)行分頁查詢只需引入用戶所需的分頁插件即可,以筆者為例,這里就直接使用pagehelper:

<!-- pagehelper 插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>

分頁查詢代碼示例

本文中筆者配置的分頁算法是通過id取模的方式,假設(shè)我們的對應(yīng)的user數(shù)據(jù)id為1,按照我們的算法,它將被存至1%3=1即user_1表:

##使用哪一列用作計(jì)算分表策略,我們就使用id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
##具體的分表路由策略,我們有3個user表,使用主鍵id取余3,余數(shù)0/1/2分表對應(yīng)表user_0,user_2,user_2
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{id % 3}

筆者在實(shí)驗(yàn)表中插入大約100w的數(shù)據(jù),進(jìn)行一次分頁查詢,其中分頁算法為id%3

@Test
    void selectByPage() {
        //查詢第2頁的數(shù)據(jù)10條
        PageHelper.startPage(2, 10, false);

        //查詢結(jié)果按照id升序排列
        UserExample userExample = new UserExample();
        userExample.setOrderByClause("id asc");
        //輸出查詢結(jié)果
        List<User> userList = userMapper.selectByExample(userExample);
        userList.forEach(System.out::println);

    }

最終結(jié)果如下,可以看到查詢結(jié)果和單表情況下是一樣的,即從11~20:

User(id=11, name=user11, phone=)
User(id=12, name=user12, phone=)
User(id=13, name=user13, phone=)
User(id=14, name=user14, phone=)
User(id=15, name=user15, phone=)
User(id=16, name=user16, phone=)
User(id=17, name=user17, phone=)
User(id=18, name=user18, phone=)
User(id=19, name=user19, phone=)
User(id=20, name=user20, phone=)

詳解sharding-jdbc對于分頁查詢的底層實(shí)現(xiàn)

按照正常的單表查詢邏輯,假設(shè)我們要查詢第2頁的數(shù)據(jù)10條,我們對應(yīng)的SQL就是:

select * from user limit (page-1)*10,size =>select * from user limit 10,10

而sharding-jdbc分表分頁查詢則比較粗暴,它會將對應(yīng)分頁及之前的數(shù)據(jù)全部查詢來,然后進(jìn)行排序,跳過對應(yīng)頁碼的數(shù)據(jù)后,再取出對應(yīng)量級的數(shù)據(jù)返回。

以我們的分頁查詢?yōu)槔鼤⒚總€分表的按照id進(jìn)行升序排列之后取出各自的前20條數(shù)據(jù),每張分表前20條數(shù)據(jù)之后,sharding-jdbc會根據(jù)我們的排序算法比對各張分表的第一條數(shù)據(jù),很明顯user_1對應(yīng)的結(jié)果最小,所以按照此規(guī)則輪詢分表的user_1、user_2、user_0以此將這3組結(jié)果存放至優(yōu)先隊(duì)列中。

基于這個隊(duì)列,sharding-jdbc會按照分頁查詢的邏輯跳過10個,所以它會不斷取出優(yōu)先隊(duì)列中的第一個元素,然后將這組分表結(jié)果再次存回隊(duì)列,以我們的查詢?yōu)槔褪?

  • 從user_1取出id為1的值,作為skip的第一個元素。
  • 將user_1查詢結(jié)果入隊(duì),因?yàn)轭^元素為4,和其他兩組比最大,所以存放至隊(duì)尾。
  • 再次從優(yōu)先隊(duì)列中拿到user_2的隊(duì)首元素2,作為skip的第2個元素,然后再次存入隊(duì)尾。
  • 依次步驟完成跳過10個。
  • 然后再按照這個規(guī)律篩選出10個,最終得到11~20。

源碼印證分頁查詢工作機(jī)制

基于上述的圖解,我們通過源碼解析方式來印證,首先mybatis會基于我們的SQL調(diào)用execute方法獲取查詢結(jié)果,然后再通過handleResultSets生成列表并返回。 我們都知道sharding-jdbc通過自實(shí)現(xiàn)數(shù)據(jù)源的同時也給出對應(yīng)的PreparedStatement即ShardingPreparedStatement,所以execute方法本質(zhì)的執(zhí)行者就是ShardingPreparedStatement,它會得到第2頁之前的所有數(shù)據(jù),然后通過handleResultSets進(jìn)行skip和limit得到最終結(jié)果:

@Override
  public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    //調(diào)用sharding-jdbc的ShardingPreparedStatement的execute獲取各個分表前2頁的所有數(shù)據(jù)
    ps.execute();
    //通過skip結(jié)合limit得到所有結(jié)果
    return resultSetHandler.handleResultSets(ps);
  }

步入execute方法可以看到其內(nèi)部本質(zhì)是調(diào)用preparedStatementExecutor進(jìn)行查詢處理的:

@Override
    public boolean execute() throws SQLException {
        try {
            clearPrevious();
            //獲取查詢SQL
            shard();
            initPreparedStatementExecutor();
            //執(zhí)行SQL結(jié)果并返回
            return preparedStatementExecutor.execute();
        } finally {
            clearBatch();
        }
    }

而該執(zhí)行方法最終會走到ShardingExecuteEngine的parallelExecute方法,通過異步查詢3張分表的結(jié)果,再通過外部傳入的回調(diào)執(zhí)行器處理這3個異步任務(wù)的查詢結(jié)果:

private <I, O> List<O> parallelExecute(final Collection<ShardingExecuteGroup<I>> inputGroups, final ShardingGroupExecuteCallback<I, O> firstCallback,
                                           final ShardingGroupExecuteCallback<I, O> callback) throws SQLException {
        Iterator<ShardingExecuteGroup<I>> inputGroupsIterator = inputGroups.iterator();
        ShardingExecuteGroup<I> firstInputs = inputGroupsIterator.next();
        //提交3個異步任務(wù)
        Collection<ListenableFuture<Collection<O>>> restResultFutures = asyncGroupExecute(Lists.newArrayList(inputGroupsIterator), callback);
        //通過回調(diào)執(zhí)行器callback阻塞獲取3個異步結(jié)果
        return getGroupResults(syncGroupExecute(firstInputs, null == firstCallback ? callback : firstCallback), restResultFutures);
    }

得到3張分表的數(shù)據(jù)之后,其內(nèi)部邏輯最終會走到ShardingPreparedStatement的getResultSet方法,其內(nèi)部會創(chuàng)建一個合并引擎DQLMergeEngine進(jìn)行并調(diào)用getCurrentResultSet進(jìn)行數(shù)據(jù)截取:

@Override
    public ResultSet getResultSet() throws SQLException {
        //......
        if (routeResult.getSqlStatement() instanceof SelectStatement || routeResult.getSqlStatement() instanceof DALStatement) {
        //反射創(chuàng)建分表合并引擎
            MergeEngine mergeEngine = MergeEngineFactory.newInstance(connection.getShardingContext().getDatabaseType(),
                    connection.getShardingContext().getShardingRule(), routeResult, connection.getShardingContext().getMetaData().getTable(), queryResults);
             //截取最終結(jié)果
            currentResultSet = getCurrentResultSet(resultSets, mergeEngine);
        }
        return currentResultSet;
    }

而該引擎就是DQLMergeEngine,進(jìn)行合并操作時,會調(diào)用LimitDecoratorMergedResult跳過前10個元素:

private MergedResult decorate(final MergedResult mergedResult) throws SQLException {
        Limit limit = routeResult.getLimit();
        //......
        //通過LimitDecoratorMergedResult跳過3張分表組合結(jié)果的前10個元素
        if (DatabaseType.MySQL == databaseType || DatabaseType.PostgreSQL == databaseType || DatabaseType.H2 == databaseType) {
            return new LimitDecoratorMergedResult(mergedResult, routeResult.getLimit());
        }
       //......
        return mergedResult;
    }

跳過的邏輯就比較簡單了,LimitDecoratorMergedResult會調(diào)用合并引擎調(diào)用OrderByStreamMergedResult的next方法跳過前10個元素:

//LimitDecoratorMergedResult的skipOffset跳過10個元素
private boolean skipOffset() throws SQLException {
        for (int i = 0; i < limit.getOffsetValue(); i++) {
        //調(diào)用OrderByStreamMergedResult跳過組合結(jié)果的前10個元素
            if (!getMergedResult().next()) {
                return true;
            }
        }
        rowNumber = 0;
        return false;
    }

可以看到OrderByStreamMergedResult的邏輯就是我們上文所說的取出隊(duì)列中的第一組查詢結(jié)果的第一個元素,然后再將其存入隊(duì)(因?yàn)槿〕龅谝粋€元素后,隊(duì)首元素最大,這組結(jié)果會存至隊(duì)尾),不斷循環(huán)跳夠10個:

@Override
    public boolean next() throws SQLException {
       //......
       //取出隊(duì)列中第一組分表查詢結(jié)果的第一個元素
        OrderByValue firstOrderByValue = orderByValuesQueue.poll();
        //如果這組分表結(jié)果還有元素則將這組分表結(jié)果入隊(duì),因?yàn)殛?duì)首元素最大,所以會存放至隊(duì)尾
        if (firstOrderByValue.next()) {
            orderByValuesQueue.offer(firstOrderByValue);
        }
       //......
        return true;
    }

經(jīng)過上述步驟跳過10個元素后,就要截取第二頁的10個數(shù)據(jù)了,代碼再次回到PreparedStatementHandler的handleResultSets方法,該方法會調(diào)用到DefaultResultSetHandler的handleRowValuesForSimpleResultMap方法,該方法會循環(huán)10個,通過resultSet.next()移到下一條數(shù)據(jù)的游標(biāo),然后生成對象存儲到resultHandler中,最終通過這個resultHandler就可以看到我們分頁查詢的List:

private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
      throws SQLException {
    DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
    ResultSet resultSet = rsw.getResultSet();
    skipRows(resultSet, rowBounds);
    //通過resultSet.next()方法調(diào)用
    while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
      storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
    }
  }

而next方法本質(zhì)還是調(diào)用LimitDecoratorMergedResult的next方法,以rowNumber 來計(jì)數(shù),調(diào)用mergedResult的next方法將游標(biāo)移動到要返回的數(shù)據(jù),

@Override
    public boolean next() throws SQLException {
       //......
       
        //同樣基于優(yōu)先隊(duì)列取夠10個
        return ++rowNumber <= limit.getRowCountValue() && getMergedResult().next();
    }

而OrderByStreamMergedResult的next邏輯和之前差不多,就是通過輪詢優(yōu)先隊(duì)列中的每一組分表對象的隊(duì)首元素,將其存到currentQueryResult中,后續(xù)進(jìn)行對象創(chuàng)建時就會從currentQueryResult中拿到這個結(jié)果生成User對象存入List中返回:

@Override
    public boolean next() throws SQLException {
     //......
     
        //從優(yōu)先隊(duì)列orderByValuesQueue拿到隊(duì)首的一組分表查詢結(jié)果
        OrderByValue firstOrderByValue = orderByValuesQueue.poll();
        //移動當(dāng)前隊(duì)列游標(biāo)
        if (firstOrderByValue.next()) {
            orderByValuesQueue.offer(firstOrderByValue);
        }
        if (orderByValuesQueue.isEmpty()) {
            return false;
        }
        //將當(dāng)前優(yōu)先隊(duì)列中的隊(duì)首元素的queryResult作為本次的查詢結(jié)果,作為后續(xù)創(chuàng)建User對象的數(shù)據(jù)
        setCurrentQueryResult(orderByValuesQueue.peek().getQueryResult());
        return true;
    }

ShardingJDBC 在查詢的時候如果沒有分表鍵會帶來什么問題

自此我們了解了sharding-jdbc分頁查詢的內(nèi)部工作機(jī)制,這里我們順便說一下這種算法的缺點(diǎn),查閱官網(wǎng)說法是sharding-jdbc分頁查詢不會占用內(nèi)存,說明查詢結(jié)果僅僅記錄的是游標(biāo):

首先,采用流式處理 + 歸并排序的方式來避免內(nèi)存的過量占用。由于SQL改寫不可避免的占用了額外的帶寬,但并不會導(dǎo)致內(nèi)存暴漲。 與直覺不同,大多數(shù)人認(rèn)為ShardingSphere會將1,000,010 * 2記錄全部加載至內(nèi)存,進(jìn)而占用大量內(nèi)存而導(dǎo)致內(nèi)存溢出。 但由于每個結(jié)果集的記錄是有序的,因此ShardingSphere每次比較僅獲取各個分片的當(dāng)前結(jié)果集記錄,駐留在內(nèi)存中的記錄僅為當(dāng)前路由到的分片的結(jié)果集的當(dāng)前游標(biāo)指向而已。 對于本身即有序的待排序?qū)ο螅瑲w并排序的時間復(fù)雜度僅為O(n),性能損耗很小。

但是筆者在使用過程中,打印內(nèi)存快照時發(fā)現(xiàn),進(jìn)行500w數(shù)據(jù)的深分頁查詢發(fā)現(xiàn),它的做法和我們上文源碼所說的一致,就是將當(dāng)前頁以及之前的結(jié)果全部加載到內(nèi)存中,所以筆者認(rèn)為使用sharding-jdbc時還是需要注意一下對內(nèi)存的監(jiān)控:

責(zé)任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關(guān)推薦

2022-05-16 08:50:23

數(shù)據(jù)脫加密器

2025-04-03 09:39:14

2021-10-27 09:55:55

Sharding-Jd分庫分表Java

2019-09-17 11:18:09

SQLMySQLJava

2024-03-14 09:30:04

數(shù)據(jù)庫中間件

2023-11-03 09:17:12

數(shù)據(jù)庫配置庫表

2020-11-06 15:30:23

分庫分表Sharding-JD數(shù)據(jù)庫

2018-12-25 16:30:15

SQL Server高效分頁數(shù)據(jù)庫

2023-07-24 09:00:00

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

2023-11-17 15:34:03

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

2009-07-15 17:00:49

JDBC查詢

2019-09-11 10:40:49

MySQL大分頁查詢數(shù)據(jù)庫

2009-09-21 13:42:47

Hibernate查詢

2010-11-18 13:40:48

mysql分頁查詢

2011-10-10 16:44:37

分頁數(shù)據(jù)庫

2009-08-04 14:23:36

ASP.NET查詢分頁

2010-04-16 16:12:51

jdbc分頁

2010-09-26 15:29:13

sql查詢分頁

2010-11-25 14:33:26

MySQL查詢分頁

2023-03-13 07:35:44

MyBatis分庫分表
點(diǎn)贊
收藏

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

jyzzz在线观看视频| 毛片毛片女人毛片毛片| 精品国产鲁一鲁****| 一区二区三区四区不卡视频| av资源一区二区| 国产精品视频久久久久久久| 精品国产精品国产偷麻豆| 欧美日韩国产高清一区| www成人免费| 激情综合闲人网| 国内成人自拍视频| 97婷婷涩涩精品一区| 国产亚洲精品精品精品| 日韩精品中文字幕一区二区| 色综合久久久久综合体| 黄瓜视频免费观看在线观看www| 国产 欧美 自拍| 免费av网站大全久久| 欧美黄色片视频| av电影在线不卡| 中文久久电影小说| 欧美少妇性性性| 女人和拘做爰正片视频| 黄av在线播放| 欧美高清一级片在线观看| 国产精品对白一区二区三区| 在线观看xxxx| 免费在线成人| 午夜精品蜜臀一区二区三区免费| 五月天婷婷丁香网| 久久99国产精品久久99大师| 欧美日韩国产成人在线91 | 在线观看一区| 中文字幕国产亚洲| 日本xxx在线播放| 51亚洲精品| 欧美精品免费视频| 妺妺窝人体色www在线观看| 鲁鲁在线中文| 亚瑟在线精品视频| 999久久欧美人妻一区二区| 你懂的在线看| 91日韩在线专区| 国产精品我不卡| 国产成人精品白浆久久69| 全国精品久久少妇| 国产成人亚洲综合91| 亚洲国产成人精品激情在线| 伊人激情综合| 欧美高跟鞋交xxxxxhd| 99久久久免费精品| 99热在线成人| 久久精品99久久久香蕉| 后入内射无码人妻一区| 日本欧美肥老太交大片| 伊人久久男人天堂| 人妻精品久久久久中文| 成人激情电影在线| 中文欧美日本在线资源| 欧美a在线播放| 日韩在线观看| 久久精品人人爽| 三级影片在线看| 888久久久| 欧美国产日韩在线| 国产性70yerg老太| 99成人在线| 日韩美女写真福利在线观看| 波多野结衣av无码| 久久精品国产99久久6| 成人欧美一区二区三区在线| 国产尤物在线观看| 国产成人在线色| 成人黄色在线免费观看| 少妇高潮一区二区三区69| 久久婷婷色综合| 相泽南亚洲一区二区在线播放 | 亚洲人成无码www久久久| 精品91久久| 欧美日韩一区二区三区视频| 中文字幕12页| 精品精品国产毛片在线看| 亚洲欧美一区二区三区情侣bbw | 中文字幕 欧美日韩| 国产精品久久久久久久久久久久久久久 | 亚洲日本韩国一区| 青青在线免费观看| xxxxx性欧美特大| 欧美日韩国产电影| 波多野结衣一二三区| 蜜臀91精品国产高清在线观看| 色婷婷**av毛片一区| 久久综合激情网| 美女黄网久久| 91久久久久久久久久久久久| 人妻偷人精品一区二区三区| 国产拍揄自揄精品视频麻豆| 国产a级黄色大片| 日产福利视频在线观看| 欧美人xxxx| 亚洲中文字幕无码一区| 欧美色蜜桃97| 国内精品久久久久影院 日本资源| 久久久精品免费看| 日韩高清在线观看| 成人自拍爱视频| 成a人v在线播放| 亚洲一级电影视频| 日本xxxx黄色| 婷婷国产精品| 欧美日本高清一区| 亚洲网站在线免费观看| aaa亚洲精品| 无码人妻精品一区二区三区99v| 中文字幕在线看片| 日韩一级完整毛片| 影音先锋男人看片资源| 亚洲综合社区| 高清视频一区| 黄av在线播放| 欧美日韩欧美一区二区| 巨胸大乳www视频免费观看| 国内久久精品| 2020国产精品久久精品不卡| 二区三区在线| 高跟丝袜一区二区三区| 久久久久亚洲AV成人网人人小说| 日韩伦理一区| 国产成人综合一区二区三区| 日本黄色大片视频| 一区二区三区欧美在线观看| 手机av在线网| 成人网18免费网站| 日韩av三级在线观看| 四虎永久在线观看| 亚洲一区二区三区四区在线| 亚洲成人av免费观看| 99热精品久久| 91久久精品美女高潮| 风间由美一区| 在线影院国内精品| 久久久久久久毛片| 日韩影院在线观看| 欧洲视频一区二区三区| 热三久草你在线| 亚洲精品一区在线观看| 精品少妇久久久| 岛国精品在线播放| 国产成人永久免费视频| a在线视频播放观看免费观看| 一区二区免费av| 欧美激情专区| 一级二级三级视频| 欧美激情一二三区| 激情五月婷婷久久| 亚洲警察之高压线| 欧美在线视频观看| 免费日韩视频在线观看| 在线天堂资源| 亚洲欧美日韩高清| 五月天中文字幕| 国产精品伦理在线| 国产探花在线看| 久久久久久久久丰满| 5566中文字幕一区二区| 欧美黑人xx片| 日韩电影在线观看永久视频免费网站| www.中文字幕在线观看| 久久久久久久久久久黄色| 亚洲 欧美 日韩系列| 日韩毛片视频| av一本久道久久波多野结衣| 国产激情在线播放| 亚洲欧洲在线看| 在线免费看91| 亚洲一区二区三区视频在线播放 | 欧美黄页在线免费观看| 久久精品国产视频| 丰满人妻av一区二区三区| 亚洲成在人线在线播放| 少妇按摩一区二区三区| 久久精品国产免费| 性一交一乱一伧国产女士spa| 欧美亚洲大陆| 国产日韩精品一区二区| www.综合网.com| 亚洲欧美国产va在线影院| 在线观看日韩一区二区| 亚洲综合色视频| 亚洲一区二区自偷自拍| 国产成人av电影在线观看| 免费观看精品视频| 亚洲精品一区二区妖精| 国产在线欧美日韩| 欧美美女福利视频| 97碰在线观看| 看黄网站在线观看| 日韩高清中文字幕| a视频免费在线观看| 色婷婷综合在线| 久久av高潮av无码av喷吹| 国产婷婷色一区二区三区在线| 91看片破解版| 久色成人在线| 日韩精品在线视频免费观看| 日韩免费一区| 九九九九九九精品| 日韩视频一二区| 国产精品日韩精品| 涩涩视频在线播放| 欧美久久久精品| 黄色国产在线| 日韩国产欧美精品一区二区三区| 国产一区二区视频免费观看| 一本色道久久加勒比精品| 青青草手机在线观看| 国产欧美一区二区精品婷婷 | 97久久人国产精品婷婷| 欧美日韩亚洲成人| 国产精品9191| 亚洲精品一二三| 亚洲欧美综合7777色婷婷| 久久久精品免费网站| 日本一级大毛片a一| 精品系列免费在线观看| 搡女人真爽免费午夜网站| 亚洲麻豆视频| 国产精品国产对白熟妇| 一区二区三区四区电影| 亚洲一区二区在线免费观看| 亚洲人成网亚洲欧洲无码| 国产欧美亚洲日本| av日韩精品| 亚洲一区二区三区四区在线播放| xxxxx.日韩| 国产精品福利在线观看| 成人性教育av免费网址| 国产91精品久久久久久| 97超碰在线免费| 午夜精品久久久久久久久久久久| 青青草原av在线| 久久91亚洲精品中文字幕奶水| 国产黄a三级三级三级av在线看| 中文字幕日韩精品有码视频| 爱久久·www| 在线看日韩欧美| av色图一区| 色视频www在线播放国产成人 | 欧美精品第一页在线播放| 一色桃子av在线| 欧美福利在线观看| 678在线观看视频| 91av福利视频| 性欧美gay| 国产精品视频在线播放| 四虎影视精品永久在线观看| 成人av番号网| 亚洲1区在线| 国产一区二区不卡视频在线观看| 日韩美女毛片| 日本一区二区在线视频| 波多野结衣的一区二区三区| 亚洲一区三区视频在线观看| 亚洲91精品| 日本wwwcom| 性娇小13――14欧美| 一区二区成人网| 国产精品一区二区三区四区| 久久久久国产免费| 91在线观看免费视频| 国产成人免费观看网站| 国产精品久久久久久一区二区三区| www.5588.com毛片| 亚洲一本大道在线| 中文字幕69页| 在线电影一区二区三区| 神马午夜电影一区二区三区在线观看| 亚洲欧美日韩另类| 国产成人高清精品| 91爱视频在线| 亚洲精品第一| 国产日韩二区| 全球成人免费直播| 丁香六月激情婷婷| 日韩av在线发布| 男人操女人下面视频| 久久一区二区视频| 亚洲av综合色区无码另类小说| aaaa一级片| 96视频在线观看欧美| 欧美精品激情blacked18| 精品丝袜在线| 国产欧美日韩免费看aⅴ视频| 亚洲综合视频在线播放| 影视一区二区三区| 国产色婷婷亚洲99精品小说| 久久av无码精品人妻系列试探| 国产精品国模大尺度视频| 久艹视频在线观看| 国产一区二区三区四区五区传媒| 五月综合激情婷婷六月色窝| 日本中文在线视频| 精品久久久久久久久久久久久久 | 欧洲激情一区二区| 亚洲国产精彩视频| 中文字幕亚洲精品| 乡村艳史在线观看| 国产日韩欧美成人| 亚洲黄色在线网站| 日韩欧美在线观看一区二区| 欧美裸体在线版观看完整版| 国产亚洲精品美女久久久久| 国产鲁鲁视频在线观看免费| 91精品一区国产高清在线gif| 亚洲人精品午夜在线观看| 国产二区在线播放| 欧美劲爆第一页| 亚洲毛片在线免费| 日本免费一区二区三区| 黄色成人91| 亚洲av毛片在线观看| 中文在线一区二区 | 亚洲动漫第一页| 国产精品第5页| 国内精品视频在线观看| 一区二区三区美女视频| 成年人视频软件| 一本久久精品一区二区| 亚洲免费不卡视频| 欧美成人精品激情在线观看| 国产视频在线免费观看| 91福利国产精品| 亚洲av成人精品一区二区三区在线播放| 另类视频在线观看| 久久精品资源| 性高潮久久久久久久久| 久久久久.com| 丰满少妇高潮一区二区| 欧美色欧美亚洲高清在线视频| 亚洲国产精品久久久久久6q| 美女999久久久精品视频| 在线不卡一区| 偷拍盗摄高潮叫床对白清晰| 极品销魂美女一区二区三区| 亚洲精品成人av久久| 欧美影院午夜播放| 爱久久·www| 国产专区欧美专区| 香蕉综合视频| 韩国三级丰满少妇高潮| 亚洲欧洲制服丝袜| av 一区二区三区| 欧美激情第1页| av成人资源网| 久久久一本二本三本| xfplay精品久久| 精品人妻一区二区三区潮喷在线| 亚洲少妇激情视频| 成人国产一区二区三区精品麻豆| 杨幂一区欧美专区| 国产美女娇喘av呻吟久久| 久久人人爽人人爽人人| 精品国产百合女同互慰| 午夜不卡影院| 色之综合天天综合色天天棕色| 麻豆成人综合网| 91嫩草丨国产丨精品| 精品国产免费视频| 欧美7777| 免费观看中文字幕| 成人视屏免费看| 国产一区二区视频免费| 日韩亚洲精品视频| 超碰97久久| 毛片av免费在线观看| 亚洲欧美另类久久久精品2019 | 欧美一级黄色录像| 九色porny丨入口在线| 图片区小说区区亚洲五月| 国产在线视频一区二区| 日韩欧美亚洲一区二区三区| 亚洲日韩中文字幕在线播放| 四虎地址8848精品| 777精品久无码人妻蜜桃| 国产精品天美传媒| 亚洲成熟女性毛茸茸| 日本午夜精品理论片a级appf发布| 久久中文字幕av| 亚洲の无码国产の无码步美| 在线观看网站黄不卡| 污污片在线免费视频| 欧美一级日本a级v片| 国产乱理伦片在线观看夜一区| 日本高清www免费视频| 中文字幕亚洲在线| 韩国精品福利一区二区三区 | 亚洲香蕉久久| 欧美 日韩 亚洲 一区| 国产精品福利av| 天天摸夜夜添狠狠添婷婷|