phoenix是一個客戶端的庫才睹,它在HBase基礎上提供SQL功能層徘跪,讓我們可以使用標準的JDBC接口操作HBase。
全部支持的特性可以瀏覽官方最新版本支持的SQL語法砂竖,下面列舉一些phoenix 4.6版本不支持的特性及與普通MySQL SQL用法有差異的地方真椿。
CHAR類型只能保存單字節(jié)的字符,不能保存中文字符乎澄,中文需要使用VARCHAR突硝。
非主鍵字段不能指定為NOT NULL,不支持指定字段默認值(4.9版本以上支持)置济。
UPDATE table SET col=val WHERE:不支持該語法解恰,phoenix更新和插入使用同樣的UPSERT INTO語法,如果主鍵存在則更新浙于,不存在則插入护盈。但可以使用UPSERT INTO table SELECT語句來實現(xiàn)條件更新,需要把主鍵按條件選出來羞酗,如:
UPSERT INTO table(id, col1) SELECT id, 'val1' FROM table WHERE col2 = val2
- DATE/TIME字段類型:這兩個字段類型對應java.sql.Date類型腐宋,其JDBC驅動不會對java.util.Date類型進行轉換,所以在PreparedStatement中setObject(int, java.util.Date)會報下面的錯誤。如果使用jfinal ActiveRecord保存實體胸竞,當實體字段是java.util.Date類型時要注意欺嗤。
java.util.Date cannot be cast to org.apache.phoenix.schema.types.PhoenixArray
LIMIT OFFSET分頁:phoenix 4.6不支持使用OFFSET分頁,在4.8以上版本才支持卫枝。
ALTER不支持改變表名煎饼、字段名與字段類型,只能增加與刪除字段校赤。在設計的時候要注意使用合適的字段類型吆玖。
大小寫:phoenix默認不區(qū)分大小寫,所有表名马篮、列名都是大寫沾乘。
不支持的函數(shù):IFNULL, ISNULL等;IFNULL有對等的COALESCE()函數(shù)
連接池:phoenix不推薦使用連接池浑测,因為其基于HBase的連接的創(chuàng)建成本很低意鲸,并且用過的HBase連接不能共享使用,因此用過的Connection需要關閉尽爆。Should I pool Phoenix JDBC Connections:
Phoenix’s Connection objects are different from most other JDBC Connections due to the underlying HBase connection. The Phoenix Connection object is designed to be a thin object that is inexpensive to create. If Phoenix Connections are reused, it is possible that the underlying HBase connection is not always left in a healthy state by the previous user. It is better to create new Phoenix Connections to ensure that you avoid any potential issues.
JDBC Connection: AutoCommit默認為false,其他JDBC Driver一般默認是true读慎,需要手動條用connnection.commit()或者在連接url后面加上";autocommit=true"
索引使用:使用CREATE INDEX idx創(chuàng)建的是全局索引(GLOBAL INDEX)漱贱,還有一種本地索引(LOCAL INDEX),相對于本地索引夭委,全局索引可以讓讀的性能更佳幅狮,但寫入的時候成本會高一點;而本地索引在寫入的時候成本較低株灸,但讀的時候成本較高崇摄。使用全局索引的時候,如果SELECT字段含有非索引的字段慌烧,則索引不會被使用逐抑,大多數(shù)情況下我們SELECT都會有索引之外的字段,這時候需要考慮建立覆蓋索引(CREATE INDEX INCLUDING ...)或使用hint來讓phoenix使用索引:SELECT /*+ INDEX(table idx) */ col FROM table WHERE ...屹蚊。
PreparedStatement不支持Statement.RETURN_GENERATED_KEYS厕氨,getGeneratedKeys()。
日期類型保存為UTC時間汹粤,在shell/squirrel查詢的時候要用CONVERT_TZ做轉換命斧,CONVERT_TZ(col, 'UTC', 'Asia/Shanghai'),但有個bug嘱兼,如果col字段是timestamp的話国葬,會報Type mismatch. expected: [DATE]。實在需要轉換的話先轉成Date類型:CONVERT_TZ(TO_DATE(TO_CHAR(col,'yyyy-MM-dd HH:mm:ss'),'yyyy-MM-dd HH:mm:ss'),'UTC','Asia/Shanghai')
優(yōu)化:
由于phoenix本質上在HBase讀寫數(shù)據(jù),所以HBase集群的性能影響是最大的汇四,一般使用多節(jié)點(一般hadoop集群節(jié)點要大于等于5個)接奈、SSD、更大的內存與緩存和對phoenix/hbase/hadoop配置參數(shù)進行調優(yōu)能獲得更大性能的提升船殉。下面列舉一些針對phoenix的優(yōu)化措施:
- 主鍵:主鍵對應HBase的row key鲫趁,HBase會把相近的row key放到相同的region里,如果選擇的主鍵是單調遞增的利虫,那么某個region就會變成熱點挨厚,寫入的性能會變差,這種情況需要在建表的使用SALT_BUCKETS=N來自動對數(shù)據(jù)分片糠惫。
- 優(yōu)化讀:使用全局索引疫剃,這會對寫入的速度有一定影響。查詢時注意使用exlain來看執(zhí)行計劃是否使用了索引硼讽。
- 優(yōu)化寫:使用本地索引巢价,建表時預先指定好分區(qū)方案(pre-split)。
- 數(shù)據(jù)是否可變:如果數(shù)據(jù)只是寫入固阁,以后不會變更壤躲,可以在建表的時候指定IMMUTABLE_ROWS=true,這樣可以提高寫入的性能备燃。
- 適當使用查詢hint來優(yōu)化執(zhí)行計劃:用explain查看執(zhí)行計劃碉克,用hint來優(yōu)化。支持的語法見hinting并齐。