phoenix 4.6 SQL注意事項(xiàng)及優(yōu)化

phoenix是一個(gè)客戶端的庫,它在HBase基礎(chǔ)上提供SQL功能層,讓我們可以使用標(biāo)準(zhǔn)的JDBC接口操作HBase。
全部支持的特性可以瀏覽官方最新版本支持的SQL語法,下面列舉一些phoenix 4.6版本不支持的特性及與普通MySQL SQL用法有差異的地方。

  • CHAR類型只能保存單字節(jié)的字符,不能保存中文字符,中文需要使用VARCHAR。

  • 非主鍵字段不能指定為NOT NULL,不支持指定字段默認(rèn)值(4.9版本以上支持)。

  • UPDATE table SET col=val WHERE:不支持該語法,phoenix更新和插入使用同樣的UPSERT INTO語法,如果主鍵存在則更新,不存在則插入。但可以使用UPSERT INTO table SELECT語句來實(shí)現(xiàn)條件更新,需要把主鍵按條件選出來,如:

UPSERT INTO table(id, col1) SELECT id, 'val1' FROM table WHERE col2 = val2
  • DATE/TIME字段類型:這兩個(gè)字段類型對應(yīng)java.sql.Date類型,其JDBC驅(qū)動不會對java.util.Date類型進(jìn)行轉(zhuǎn)換,所以在PreparedStatement中setObject(int, java.util.Date)會報(bào)下面的錯誤。如果使用jfinal ActiveRecord保存實(shí)體,當(dāng)實(shí)體字段是java.util.Date類型時(shí)要注意。
java.util.Date cannot be cast to org.apache.phoenix.schema.types.PhoenixArray
  • LIMIT OFFSET分頁:phoenix 4.6不支持使用OFFSET分頁,在4.8以上版本才支持。

  • ALTER不支持改變表名、字段名與字段類型,只能增加與刪除字段。在設(shè)計(jì)的時(shí)候要注意使用合適的字段類型。

  • 大小寫:phoenix默認(rèn)不區(qū)分大小寫,所有表名、列名都是大寫。

  • 不支持的函數(shù):IFNULL, ISNULL等;IFNULL有對等的COALESCE()函數(shù)

  • 連接池:phoenix不推薦使用連接池,因?yàn)槠浠贖Base的連接的創(chuàng)建成本很低,并且用過的HBase連接不能共享使用,因此用過的Connection需要關(guān)閉。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默認(rèn)為false,其他JDBC Driver一般默認(rèn)是true,需要手動條用connnection.commit()或者在連接url后面加上";autocommit=true"

  • 索引使用:使用CREATE INDEX idx創(chuàng)建的是全局索引(GLOBAL INDEX),還有一種本地索引(LOCAL INDEX),相對于本地索引,全局索引可以讓讀的性能更佳,但寫入的時(shí)候成本會高一點(diǎn);而本地索引在寫入的時(shí)候成本較低,但讀的時(shí)候成本較高。使用全局索引的時(shí)候,如果SELECT字段含有非索引的字段,則索引不會被使用,大多數(shù)情況下我們SELECT都會有索引之外的字段,這時(shí)候需要考慮建立覆蓋索引(CREATE INDEX INCLUDING ...)或使用hint來讓phoenix使用索引:SELECT /*+ INDEX(table idx) */ col FROM table WHERE ...。

  • PreparedStatement不支持Statement.RETURN_GENERATED_KEYS,getGeneratedKeys()。

  • 日期類型保存為UTC時(shí)間,在shell/squirrel查詢的時(shí)候要用CONVERT_TZ做轉(zhuǎn)換,CONVERT_TZ(col, 'UTC', 'Asia/Shanghai'),但有個(gè)bug,如果col字段是timestamp的話,會報(bào)Type mismatch. expected: [DATE]。實(shí)在需要轉(zhuǎn)換的話先轉(zhuǎn)成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本質(zhì)上在HBase讀寫數(shù)據(jù),所以HBase集群的性能影響是最大的,一般使用多節(jié)點(diǎn)(一般hadoop集群節(jié)點(diǎn)要大于等于5個(gè))、SSD、更大的內(nèi)存與緩存和對phoenix/hbase/hadoop配置參數(shù)進(jìn)行調(diào)優(yōu)能獲得更大性能的提升。下面列舉一些針對phoenix的優(yōu)化措施:

  • 主鍵:主鍵對應(yīng)HBase的row key,HBase會把相近的row key放到相同的region里,如果選擇的主鍵是單調(diào)遞增的,那么某個(gè)region就會變成熱點(diǎn),寫入的性能會變差,這種情況需要在建表的使用SALT_BUCKETS=N來自動對數(shù)據(jù)分片。
  • 優(yōu)化讀:使用全局索引,這會對寫入的速度有一定影響。查詢時(shí)注意使用exlain來看執(zhí)行計(jì)劃是否使用了索引。
  • 優(yōu)化寫:使用本地索引,建表時(shí)預(yù)先指定好分區(qū)方案(pre-split)。
  • 數(shù)據(jù)是否可變:如果數(shù)據(jù)只是寫入,以后不會變更,可以在建表的時(shí)候指定IMMUTABLE_ROWS=true,這樣可以提高寫入的性能。
  • 適當(dāng)使用查詢hint來優(yōu)化執(zhí)行計(jì)劃:用explain查看執(zhí)行計(jì)劃,用hint來優(yōu)化。支持的語法見hinting。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容