使用參數(shù)化查詢提高Cypher查詢的性能:以華為云圖引擎GES為例
在DBMS中,參數(shù)化查詢被視為一種有效預(yù)防SQL注入攻擊的手段。華為云圖引擎GES提供對gremlin和cypher查詢語言的參數(shù)化查詢支持,使用參數(shù)化查詢不僅可以防止前端用戶隨意輸入惡意指令影響語句執(zhí)行,還可以有效利用查詢編譯緩存,提高查詢性能。
參數(shù)化查詢(Parameterized Query),Wiki中的解釋是:客戶端在向數(shù)據(jù)服務(wù)端發(fā)送和請求查詢語句時,在需要填入數(shù)值或者用戶輸入的字符串數(shù)據(jù)的地方,使用一個變量名來替代,并在請求體中解釋每個變量名所指代的內(nèi)容。在這種情況下,由于變量名指代的內(nèi)容不會參與SQL語言的查詢編譯,即使用戶輸入數(shù)據(jù)中包含一些破壞性的指令,也不會被數(shù)據(jù)庫運行。
舉例說明,使用Cypher-JDBC-Driver訪問華為云圖引擎,可以進行對應(yīng)的參數(shù)設(shè)置:
public static void main(String[] args) throws ClassNotFoundException { Class.forName("com.huawei.ges.jdbc.Driver"); String url = "jdbc:ges:http://{{graph_ip}}:{{graph_port}}/ges/v1.0/{{project_id}}/graphs/{{graph_name}}/action?action_id=execute-cypher-query"; url = url.replace("{{graph_ip}}", ip).replace("{{graph_port}}",port + "").replace("{{project_id}}", projectId).replace("{{graph_name}}", graphName); Properties prop = new Properties(); prop.setProperty("X-Auth-Token", token); try(Connection conn = DriverManager.getConnection(url,prop)){ String query = "match (n:movie) where n.genres=? return n.title"; try(PreparedStatement stmt = conn.prepareStatement(query)){ stmt.setString(1, "Comedy"); try(ResultSet rs = stmt.executeQuery()){ while(rs.next()) { System.out.println(rs.getString("n.title")); } } } } catch (SQLException e) { // do something for e. } }
其中查詢語句中的問號即是JDBC風(fēng)格的參數(shù)化查詢變量,后面代碼中通過setString方法為其設(shè)置一個值“Comedy”。此外,圖引擎也支持restful api風(fēng)格的參數(shù)化查詢,詳見官網(wǎng)文檔。
同時,參數(shù)化查詢可以使得不同的用戶輸入使用同一條參數(shù)化查詢語句執(zhí)行,可以高效利用數(shù)據(jù)庫查詢緩存,節(jié)省了查詢編譯時間,從而提升了查詢性能。例如,下圖是使用Freebase數(shù)據(jù)集構(gòu)造的若干2跳3跳查詢,在華為云圖引擎GES中運行, 參數(shù)化查詢前后QPS的變化。可以看到使用參數(shù)化查詢,qps獲得了2-8倍的提升。
為什么參數(shù)化查詢可以提高查詢qps?首先要簡單介紹下數(shù)據(jù)服務(wù)在收到查詢語句后都做了什么。在數(shù)據(jù)管理領(lǐng)域,數(shù)據(jù)服務(wù)接收到查詢語句,往往會進行下列步驟: 詞法&語法解析,查詢計劃生成,查詢計劃執(zhí)行,如圖。
這里簡單說一下查詢計劃生成。現(xiàn)在大多數(shù)查詢計劃的生成策略,要么是基于代價的查詢計劃生成,要么是基于規(guī)則的查詢計劃生成,或者二者組合使用。而不管是哪種查詢計劃生成,都是偏向計算密集型的任務(wù),比較耗費服務(wù)器的計算資源,同一時間系統(tǒng)只能并行處理有限數(shù)目的查詢計劃生成任務(wù)。在計劃生成器內(nèi)部,大多數(shù)數(shù)據(jù)庫都會內(nèi)置查詢緩存,即在一定的時間范圍內(nèi),同一條查詢語句輸入計劃器,計劃器優(yōu)先從查詢緩存中檢查有無可用計劃,如果緩存中生成的計劃時間太長或者無可用計劃,才會真正執(zhí)行計劃生成的過程。
因此使用參數(shù)化查詢時,由于使用不同參數(shù)的查詢語句語句體相同,在查詢編譯階段更容易被認為是同一條查詢語句, 從而實現(xiàn)“多次查詢,一次編譯”的效果,也就提高了查詢編譯效率。
附錄:
Freebase數(shù)據(jù)集屬性圖格式規(guī)模:
查詢語句:
2hop_Q1: match (n1)-[r]->(m1)-->(p1) where id(n1)=$vertex return id(p1) limit 100
2hop_Q2: match (n1)-[r]->(m1)-->(p1) where id(n1)=$vertex return p1.name limit 100
2hop_Q3: match(n)-[r]->(m)-->(p) where id(n)=$vertex and m.games > 10 and p.name contains 'NBA' return p
3hop_Q1: match (n1)-[r1]-(m1)-[r2]-(p1)--(p2) where id(n1)=$vertex and m1.game > 0 return id(p2) limit 100
3hop_Q2: match (n1)-[r1]-(m1) match (m1)-[r2]-(p1) match (p1)--(p2) where id(n1)=$vertex and m1.games > 0 return id(p2)
相關(guān)參考:
[1]參數(shù)化查詢_百度百科:https://baike.baidu.com/item/%E5%8F%82%E6%95%B0%E5%8C%96%E6%9F%A5%E8%AF%A2/4841802?fr=aladdin
[2]GES cypher API: https://support.huaweicloud.com/api-ges/ges_03_0212.html
[3]Github - opencypher:https://github.com/opencypher/openCypher
云端實踐 圖引擎服務(wù) GES 數(shù)據(jù)庫
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。