1. 程式人生 > >SQL on HBase -- phoenix 之分頁查詢

SQL on HBase -- phoenix 之分頁查詢

        最近一個專案中使用了HBase,有一部分實時查詢的需求。HBase本身只有一種排序,即按照rowkey的字典升序來排序資料。然而我們常常會碰到各種各樣的排序需求。

        對於簡單的需求(比如專案確定只有某一種特定排序的需求),則可以通過對rowkey本身進行“組合”設計來達到目的。比如專案涉及到的資料為全球各類學校學生情況,需要按照在校人數的降序來展示資料,則可以採用“Integer.MAX_VALUE - 在校人數 + 學校簡稱” 組成rowkey(注意保證整數部分佔有相同位元組數)。

        對於稍微複雜一點的需求,比如需要有分別按照某幾列排序的功能,可以考慮對這幾列建立二級索引表,索引表的rowkey為該列的每一個值,索引表只含一列,列值為對應的原資料的rowkey。當選擇按照某一列進行排序時,首先讀取索引表的內容,進而再根據索引表的列值再向原資料表發起查詢,得到按照該列進行排序後的資料。關於建立二級索引表有很多的討論,感興趣的小夥伴可以自行去了解。

        第三種需求,就是我目前碰到的問題。專案有N張資料表,每張表都可以自定義查詢條件,並可以按照每一列進行排序。這要是用SQL,簡直就太開心啦,分分鐘的事情。可是我面對的是HBase,而且我是個初學者,跟小白差不多,只熟練掌握了各種filter的使用,自定義查詢條件的需求可以輕鬆搞定,但排序就哭了。聽聞HBase的coprocessor功能強大,有網友提到可以用它來做排序,可能我太愚蠢,看來看去,就覺得coprocessor跟spring裡的aop概念有一拼,實在想不出它能跟排序有幾毛錢關係。

        迷茫中看到了Hive,但是Hive是把SQL語句轉化成map reduce來做的,並不適合做實時查詢。

        然後看到了phoenix,phoenix官網上是這麼詮釋它的:High performance relational database layer over HBase for low latency applications。一些測評資料也顯示,在100M行以內的資料集上,phoenix的效能遠超Hive,可以在數秒內甚至毫秒級別得到結果(Hive基本上是幾十秒起步)。正好符合我的需求。

        這時問題來了,怎麼在phoenix上做分頁呢?

        傳統SQL的LIMIT關鍵字可以跟兩個引數,一個是起始index,一個是需要的行數,做分頁so easy啊。但phoenix的LIMIT只支援一個引數:需要的行數。

        在原始的HBase上做分頁也比較簡單,可以使用PageFilter設定需要的行數,再根據逐頁查詢記錄下每一頁起始行的rowkey,來設定Scan的起始rowkey。

        查了phoenix的issues,phoenix的開發者推薦了一種做法:使用組合條件,組合排序依據的列值及rowkey。下面舉例子說明具體做法。

        有一張表,包含關鍵字PK(及原始HBase中的rowkey),以及若干列ORG_NAME, ORG_NUM, ORG_CODE等等。(其中PK的大小和該行資訊的新舊程度成反比,即PK越小,該條資訊越新)

        現在需要可以自定義了查詢條件後,再根據任一列進行排序,比如當ORG_NAME為“一”時,根據ORG_CODE做升序、降序,每頁資料為20條。

        1. 查詢第一頁時:

           (1) SELECT * FROM ORG WHERE ORG_NAME = '一'

                 ORDER BY ORG_CODE ASC, PK ASC LIMIT 21 (升序)

           (2) SELECT * FROM ORG WHERE ORG_NAME = '一'

                 ORDER BY ORG_CODE DESC, PK DESC LIMIT 21 (降序)

            每頁資料為20條,但我們這裡取了21條,這個很關鍵,第21條就是第二頁的第一行,需要記錄下這行的ORG_CODE值(記為CODE2),以及PK(記為PK2),為第二頁的查詢做鋪墊。

        2.查詢第二頁時:

           (1) SELECT * FROM ORG WHERE ORG_NAME='一' AND

                (ORG_CODE = CODE2 AND PK >= PK2 OR ORG_CODE > CODE2)

                ORDER BY ORG_CODE ASC ,PK ASC LIMIT 21(升序)

           (2) SELECT * FROM ORG WHERE ORG_NAME='一' AND

                (ORG_CODE = CODE2 AND PK >= PK2 OR ORG_CODE < CODE2)

                ORDER BY ORG_CODE DESC ,PK ASC LIMIT 21(降序)

        後面的頁數依次類推,將CODE2和PK2替換為相應的值即可

        回頭想想,這個做法其實就是結合了SQL的分頁做法和HBase的分頁做法,就跟phoenix本身一樣——為SQL和HBase搭起了溝通的橋樑。

        雖然phoenix還是存在一些問題:沒法對中文進行有意義的排序。mysql對中文的有意義排序可以通過設定字符集為GBK來解決,而phoenix目前只能處理utf-8編碼的資料,用GBK編碼資料存到HBase中,直接從HBase中讀出來沒有問題,但通過phoenix讀出來就全成了亂碼。給phoenix的mailing list發了郵件,一直未收到回覆,期待有中國的大神以後可以給phoenix打個補丁。

        困擾了我很久的HBase按列排序問題終於得到了還算妥善的解決,心情真是美麗啊。凡事還是要多學習,多實踐才好,繼續加油哦。

相關推薦

SQL on HBase -- phoenix 查詢

        最近一個專案中使用了HBase,有一部分實時查詢的需求。HBase本身只有一種排序,即按照rowkey的字典升序來排序資料。然而我們常常會碰到各種各樣的排序需求。         對於簡單的需求(比如專案確定只有某一種特定排序的需求),則可以通過對rowk

MySQL(十)DQL查詢

-c lar jpg not 列表 img IE class HERE 一、應用場景 當要查詢的條目數太多,一頁顯示不全 二、語法 select 查詢列表 from 表 limit 【offset,】size; 2.1、註意: ffset代表的是起始的條目索引,默認從0卡死

MongoDB動態條件查詢

實體類 其他 integer att 字符串匹配 uil .class bsp ddc 一、使用QueryByExampleExecutor 1. 繼承MongoRepository public interface StudentRepository extends M

mysql 查詢

alt mysq style 我只 rom font 分頁 插入 com 分頁查詢(limit 起始行,查詢幾行) 如果 我只想插入 第一第二行的數據 該怎麽做那 select from student limit 0,2; 分頁查詢當前頁數的數據 select *

Spring Data JPA 查詢

JPA的分頁查詢確實使用起來確實很簡單,但理解起來有點困難,此處只是實現JPA分頁的程式碼塊。 定義實體類: @Entity @Table(name = "t_pub_info") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_REA

SpringBoot學習筆記10——spring-data-jpa查詢

今天我們來學習一下spring-data-jpa的分頁查詢的實現 在上次初探JPA之後我們接下來學習分頁查詢,本篇部落格是接上一篇的,如果有需要了解jpa配置的話可以看上一篇部落格https://blog.csdn.net/lp840312696/article/details/83549937

mongoDB查詢 skip() limit()

在研究 mongo 分頁查詢的過程中,發現數據量大了之後,就查詢特別慢;在研究中發現,mongo 處理資料主要依賴記憶體,在 cpu,memory 的佔用率過高的情況下,mongoDB 的效率就會直線下降;所以在對 mongo 操作的過程中,要注意記憶體的消耗;不可做任何佔用大量記憶體的事情;

效能優化查詢

一、背景 大部分開發和DBA同行都對分頁查詢非常非常瞭解,看帖子翻頁需要分頁查詢,搜尋商品也需要分頁查詢。那麼問題來了,遇到上千萬或者上億的資料量怎麼快速的拉取全量,比如大商家拉取每月千萬級別的訂單數量到自己獨立的ISV做財務統計;或者擁有百萬千萬粉絲的公眾大號,給全部粉絲推送訊息的場景。本文講講個人的優化

django查詢

.html lac html ive path com lse font port 1.自定義分頁函數 #第一個參數:request對象;第二個參數:需要分頁的數據;第三個參數:每頁顯示的數據個數;第四個參數:需要返回的網頁---->"myadmin/user/ind

mybatis查詢

1)StudentDao.java /** * 持久層*/ public class StudentDao { /** * 增加學生 */ public void add(Student student) throws Exception{

SpringBoot 查詢

前言 學習資料庫很久了,並且對於CRUD(增、刪、改、查)已經爛熟於心了,相信許多跟我一樣還天天對於資料庫的操作僅限於此的朋友們一定早已感到枯燥了,那麼我們趕緊進入話題,來談談分頁查詢的使用吧! (基本上是第一次寫部落格,有錯的或是言語不當的地方還望多多指教

MongoDB 效能優化查詢

最常見的分頁採用的是skip+limit這種組合方式,這種方式對付小資料倒也可以,但是對付上幾百上千萬的大資料,只能力不從心。通過如下思路改善,可以大大提高查詢速度:條件查詢+排序+限制返回記錄。邊查詢,邊排序,排序之後,抽取第一次分頁中的最後一條記錄,作為第二次分頁的條件

Lucene查詢的三種方式-yellowcong

分頁查詢有三種,一種是直接查詢出這頁及這頁以後的資料,第二種,查詢這頁以前的最後一條資料,然後再查詢這頁之後的資料,這種方式還不如第一種方法快,第三種,是根據一個id來進行分頁,這種方式適合不變更的資料 方法1 思路是將所有的查詢取來,然後取自己當前

JPA+Spring程式設計查詢

SpringData中的PagingAndSortingRepository自帶了findall方法: Page<T> findAll(Pageable var1); 引數為Pageable,返回Page型別的資料。是用此方法就可以實現分頁查詢。

SQL 分割字串和通用查詢儲存過程

USE [sg]  --使用某個資料庫 GO /****** Object:  StoredProcedure [dbo].[findTableIndex]    Script Date: 2017/4/1 17:02:58 ******/ SET ANSI_NULLS

項目代碼設計規範總結查詢

最終 實現 當前 crm int 心悅 是否 管理系統 總頁數 如今的項目,不管是cms,crm等等諸如這類的關系管理或是內容管理系統的項目,分頁是一個剛需,那有沒有一個比較標準的分頁功能的設計規範呢,今天在一個開源項目中就看到了其他大神寫的分頁功能,確實是賞心悅目的代碼。

HBase偽快速查詢

    之前有兩個功能,都是查詢歷史資料的一個分頁查詢,系統剛上線的時候,沒有太多的資料,就一直扔在mysql裡面,後來裡面資料上億之後,就查不到了,而且資料還在以指數級增長方式上報,後來,這部分業務單

hadoophbase資料查詢

package page; import java.io.IOException; import java.util.Iterator; import org.apache.hadoop.conf.Configuration; import org.apac

mybatis查詢sql server--mysql

         在習慣了使用mysql進行資料操作後,突然轉到sql server,雖然說兩者在mybatis中的語法基本相同,很容易替換,但是,這也是最容易出問題的地方,因為往往我們會被這些些微的“不同”坑害。          今天這裡就分享一下mysql和sql s

HBase多條件及查詢的一些方法

nosql數據庫 應用場景 實現簡單 信息 byte 多條 多個 不可用 寫性能 HBase是Apache Hadoop生態系統中的重要一員,它的海量數據存儲能力,超高的數據讀寫性能,以及優秀的可擴展性使之成為最受歡迎的NoSQL數據庫之一。它超強的插入和讀取性能與它的數據