2017-01-11 9 views
0

サンプルデータのmemsqlパフォーマンステストを実行していますが、JSONデータを照会するときの動作が非常に悪いです。 私は2つのテーブルが非常によく似ていて、同じ情報を含んでいます(同じcsvファイルからロードされています)。相違点は、segments列がJSONとvarchar(255)であることです。MemSQLの検索パフォーマンス:JSON vs varchar

CREATE TABLE `test_events` (
`timestamp` datetime NOT NULL, 
`user_id` int(20) NOT NULL, 
`segments` JSON COLLATE utf8_bin NOT NULL, 
KEY `timestamp` (`timestamp`) /*!90619 USING CLUSTERED COLUMNSTORE */, 
/*!90618 SHARD */ KEY `user_id` (`user_id`) 


CREATE TABLE `test_events_string` (
`timestamp` datetime NOT NULL, 
`user_id` int(20) NOT NULL, 
`segments` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', 
KEY `timestamp` (`timestamp`) /*!90619 USING CLUSTERED COLUMNSTORE */, 
/*!90618 SHARD */ KEY `user_id` (`user_id`) 

および実施例のデー​​タは、(アレイ内の項目の量は1から20まで変化)である。

以下
memsql> select * from test_events limit 1; 
+---------------------+---------+------------------------+ 
| timestamp   | user_id | segments    | 
+---------------------+---------+------------------------+ 
| 2017-01-04 00:00:00 | 26834 | [19,18,9,6,7,22,34,43] | 
+---------------------+---------+------------------------+ 

は、同じ情報をフェッチ2つのクエリであるが、速度は異なっています。両方のクエリが2回実行され、2回目の実行がコピーされます。

memsql> select count(*) from test_events where json_array_contains_double(segments, 42); 
+----------+ 
| count(*) | 
+----------+ 
| 79312103 | 
+----------+ 
1 row in set (15.86 sec) 

memsql> select count(*) from test_events_string where segments like '%42%'; 
+----------+ 
| count(*) | 
+----------+ 
| 79312103 | 
+----------+ 
1 row in set (1.96 sec) 

memsql> select count(*) from test_events; 
+-----------+ 
| count(*) | 
+-----------+ 
| 306939340 | 
+-----------+ 
1 row in set (0.02 sec) 

したがって、JSONスキャンは%x%LIKEよりも8倍遅くなります。それを改善できるものはありますか?

多分、あなたは別のアプローチでビジネスロジックの問題を解決する方法をアドバイスできますか?基本的には、ユーザーのイベントとイベントのログを、いくつかのエンティティのIDの配列を添付してログに記録します。この配列は、ユーザーのライフサイクル中に頻繁に変更されます。上記の例のように、1つまたは複数のIDでフィルタリングするクエリを実行します。

場合によっては、一部の技術仕様。 3つの同一のベアメタルサーバ。 1サーバーはアグリゲーター用、2はデータ用です。各マシンにNUMAがあるため、4つのリーフノードが合計されます。高速SSD、32Cores(2 X [email protected])、32GB RAM

答えて

1

私はこれが遅いのは驚きではありません。 MemSQLは、円柱jsonのための寄木張りベースの圧縮を使用していますが、これらの種類の高速検索はまだありません(ただし、調整は続けてください)。

いくつかのオプションがあります。 常に42を検索する場合は、永続カラム(https://docs.memsql.com/docs/persistent-computed-columns)を使用できます。 これはあなたのユースケースではないようです。

他のオプションは、常に同じ配列を参照している場合、正規化されたテーブル(https://en.wikipedia.org/wiki/Database_normalization)を作成することです。
と同じように create table test_events_array (timestamp datetime not null, user_id bigint not null, segment bigint, shard(user_id), key(ts) using clustered columnstore) すると、 select count(*) from test_events_array where segment=42のようになります。

おそらく、そのスキーマではほとんど何も圧縮されません。

関連する問題