Skip to main content
Edit this page

NYPD Complaint Data

タブ区切り値ファイル (TSV) は一般的で、ファイルの最初の行にフィールド見出しが含まれる場合があります。ClickHouseはTSVを取り込むことができ、また、ファイルを取り込まずにTSVにクエリを実行することも可能です。このガイドではこれらのケースを扱います。CSVファイルにクエリを実行または取り込む必要がある場合、フォーマット引数のTSVCSVに置き換えるだけで同様の方法が適用できます。

このガイドを通じて、以下のことを行います:

  • 調査: TSVファイルの構造と内容をクエリします。
  • ターゲットとするClickHouseスキーマを決定: 適切なデータ型を選び、既存のデータをそれらの型にマッピングします。
  • ClickHouseテーブルを作成します。
  • データを前処理してClickHouseにストリームします。
  • ClickHouseに対していくつかのクエリを実行します。

このガイドで使用するデータセットはニューヨーク市のオープンデータチームから提供され、"ニューヨーク市警察 (NYPD) に報告されたすべての有効な重罪、軽犯罪、違反に関するデータ"が含まれています。執筆時点でデータファイルのサイズは166MBですが、定期的に更新されています。

ソース: data.cityofnewyork.us 利用規約: https://www1.nyc.gov/home/terms-of-use.page

前提条件

このガイドで説明されるコマンドについての注意

このガイドには2種類のコマンドがあります:

  • 一部のコマンドはTSVファイルにクエリを実行するもので、これらはコマンドプロンプトで実行されます。
  • その他のコマンドはClickHouseにクエリを実行するもので、これらはclickhouse-clientまたはPlay UIで実行されます。
Note

このガイドの例は、TSVファイルを${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsvに保存したと仮定しています。必要に応じてコマンドを調整してください。

TSVファイルに慣れ親しむ

ClickHouseデータベースを使用する前に、データに慣れ親しんでください。

ソースTSVファイルのフィールドを確認する

これがTSVファイルにクエリを実行するコマンドの例です。ただし、まだ実行しないでください。

clickhouse-local --query \
"describe file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')"

サンプルレスポンス

CMPLNT_NUM                  Nullable(Float64)
ADDR_PCT_CD Nullable(Float64)
BORO_NM Nullable(String)
CMPLNT_FR_DT Nullable(String)
CMPLNT_FR_TM Nullable(String)
Tip

多くの場合、上記のコマンドは入力データの中で数値フィールドと文字列フィールド、およびタプルであるフィールドを教えてくれます。これは常にそうではありません。ClickHouseは何億ものレコードを含むデータセットでルーチンに使用されるため、スキーマを推測するために既定の行数(100)が調べられますが、これはスキーマを推測するために何十億もの行を解析することを避けるためです。以下のレスポンスは、データセットが毎年数回更新されるため、お客様が見る内容とは一致しないかもしれません。データディクショナリーを見ると、CMPLNT_NUMがテキストとして指定されており、数値ではありません。スキーマ推測のための入力行数を100から設定SETTINGS input_format_max_rows_to_read_for_schema_inference=2000にオーバーライドすると、より良いコンテンツの理解ができます。

バージョン22.5以降、推測のためのデフォルト行数が25,000行に変更されているため、古いバージョンの場合や25,000行以上のサンプルが必要な場合にのみ設定を変更してください。

このコマンドをコマンドプロンプトで実行してください。clickhouse-localを使用してダウンロードしたTSVファイル内のデータにクエリを実行します。

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"describe file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')"

結果:

CMPLNT_NUM        Nullable(String)
ADDR_PCT_CD Nullable(Float64)
BORO_NM Nullable(String)
CMPLNT_FR_DT Nullable(String)
CMPLNT_FR_TM Nullable(String)
CMPLNT_TO_DT Nullable(String)
CMPLNT_TO_TM Nullable(String)
CRM_ATPT_CPTD_CD Nullable(String)
HADEVELOPT Nullable(String)
HOUSING_PSA Nullable(Float64)
JURISDICTION_CODE Nullable(Float64)
JURIS_DESC Nullable(String)
KY_CD Nullable(Float64)
LAW_CAT_CD Nullable(String)
LOC_OF_OCCUR_DESC Nullable(String)
OFNS_DESC Nullable(String)
PARKS_NM Nullable(String)
PATROL_BORO Nullable(String)
PD_CD Nullable(Float64)
PD_DESC Nullable(String)
PREM_TYP_DESC Nullable(String)
RPT_DT Nullable(String)
STATION_NAME Nullable(String)
SUSP_AGE_GROUP Nullable(String)
SUSP_RACE Nullable(String)
SUSP_SEX Nullable(String)
TRANSIT_DISTRICT Nullable(Float64)
VIC_AGE_GROUP Nullable(String)
VIC_RACE Nullable(String)
VIC_SEX Nullable(String)
X_COORD_CD Nullable(Float64)
Y_COORD_CD Nullable(Float64)
Latitude Nullable(Float64)
Longitude Nullable(Float64)
Lat_Lon Tuple(Nullable(Float64), Nullable(Float64))
New Georeferenced Column Nullable(String)

この時点で、TSVファイルのカラムがデータセットのウェブページこのデータセットのカラムセクションで指定されている名前と型に一致するか確認してください。データ型は非常に具体的ではなく、すべての数値フィールドはNullable(Float64)に設定され、その他のフィールドはすべてNullable(String)となっています。データを保存するClickHouseテーブルを作成する際に、より適切でパフォーマンスに優れた型を指定できます。

適切なスキーマを決定する

フィールドに使用すべき型を判断するには、データがどのように見えるかを知る必要があります。例えば、JURISDICTION_CODEフィールドは数値ですが、UInt8にすべきか、Enumにすべきか、それともFloat64が適切かを判断します。

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select JURISDICTION_CODE, count() FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
GROUP BY JURISDICTION_CODE
ORDER BY JURISDICTION_CODE
FORMAT PrettyCompact"

結果:

┌─JURISDICTION_CODE─┬─count()─┐
│ 0 │ 188875 │
│ 1 │ 4799 │
│ 2 │ 13833 │
│ 3 │ 656 │
│ 4 │ 51 │
│ 6 │ 5 │
│ 7 │ 2 │
│ 9 │ 13 │
│ 11 │ 14 │
│ 12 │ 5 │
│ 13 │ 2 │
│ 14 │ 70 │
│ 15 │ 20 │
│ 72 │ 159 │
│ 87 │ 9 │
│ 88 │ 75 │
│ 97 │ 405 │
└───────────────────┴─────────┘

このクエリのレスポンスは、JURISDICTION_CODEUInt8に適していることを示しています。

同様に、一部のStringフィールドを確認して、それらがDateTimeまたはLowCardinality(String)フィールドに適しているかを確認します。

例えば、PARKS_NMフィールドは"発生場所の適用がある場合はNYCの公園、遊び場、またはグリーンスペースの名前(州立公園は含まれません)"と説明されています。ニューヨーク市の公園の名前は、LowCardinality(String)に適している可能性があります。

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select count(distinct PARKS_NM) FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─uniqExact(PARKS_NM)─┐
│ 319 │
└─────────────────────┘

いくつかの公園名を見てみましょう:

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select distinct PARKS_NM FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
LIMIT 10
FORMAT PrettyCompact"

結果:

┌─PARKS_NM───────────────────┐
│ (null) │
│ ASSER LEVY PARK │
│ JAMES J WALKER PARK │
│ BELT PARKWAY/SHORE PARKWAY │
│ PROSPECT PARK │
│ MONTEFIORE SQUARE │
│ SUTTON PLACE PARK │
│ JOYCE KILMER PARK │
│ ALLEY ATHLETIC PLAYGROUND │
│ ASTORIA PARK │
└────────────────────────────┘

執筆時のデータセットには、PARK_NMカラムに数百の異なる公園や遊び場しか含まれていません。これは、LowCardinality推奨のLowCardinalityフィールドにおける 10,000未満の異なる文字列を保つための小さな数値です。

DateTimeフィールド

データセットのウェブページこのデータセットのカラムセクションに基づき、報告されたイベントの開始と終了の日付と時間フィールドがあります。CMPLNT_FR_DTとCMPLT_TO_DTの最小値と最大値を確認すると、フィールドが常に入力されているかどうか分かります。

CMPLNT_FR_DT
clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select min(CMPLNT_FR_DT), max(CMPLNT_FR_DT) FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─min(CMPLNT_FR_DT)─┬─max(CMPLNT_FR_DT)─┐
│ 01/01/1973 │ 12/31/2021 │
└───────────────────┴───────────────────┘
CMPLNT_TO_DT
clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select min(CMPLNT_TO_DT), max(CMPLNT_TO_DT) FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─min(CMPLNT_TO_DT)─┬─max(CMPLNT_TO_DT)─┐
│ │ 12/31/2021 │
└───────────────────┴───────────────────┘
CMPLNT_FR_TM
clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select min(CMPLNT_FR_TM), max(CMPLNT_FR_TM) FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─min(CMPLNT_FR_TM)─┬─max(CMPLNT_FR_TM)─┐
│ 00:00:00 │ 23:59:00 │
└───────────────────┴───────────────────┘
CMPLNT_TO_TM
clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select min(CMPLNT_TO_TM), max(CMPLNT_TO_TM) FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─min(CMPLNT_TO_TM)─┬─max(CMPLNT_TO_TM)─┐
│ (null) │ 23:59:00 │
└───────────────────┴───────────────────┘

プランを立てる

上記の調査結果に基づき:

  • JURISDICTION_CODEUInt8としてキャストする必要があります。
  • PARKS_NMLowCardinality(String)にキャストするべきです。
  • CMPLNT_FR_DTCMPLNT_FR_TMは常に入力されています(おそらくデフォルトの時間00:00:00で)
  • CMPLNT_TO_DTCMPLNT_TO_TMは空欄の可能性があります
  • ソースでは、日付と時刻が分割されたフィールドに保存されています
  • 日付はmm/dd/yyyy形式です
  • 時間はhh:mm:ss形式です
  • 日付と時間はDateTime型に連結できます
  • 1970年1月1日以前のデータが含まれるため、64ビットのDateTimeが必要です
Note

型に加えるべき変更は多数ありますが、すべて同じ調査手順に従って決定できます。フィールドの低位数文字列の数や、最小値と最大値を確認して決定します。このガイドの後のテーブルスキーマは、LowCardinalityの文字列と符号なし整数フィールドが多く、浮動小数点数値フィールドは非常に少数です。

日付と時間のフィールドを連結する

日時フィールドCMPLNT_FR_DTCMPLNT_FR_TMを1つのStringに連結してDateTime型にキャストできるようにします。まず2つのフィールドを連結演算子で結合します: CMPLNT_FR_DT || ' ' || CMPLNT_FR_TMCMPLNT_TO_DTCMPLNT_TO_TMフィールドも同様に処理されます。

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select CMPLNT_FR_DT || ' ' || CMPLNT_FR_TM AS complaint_begin FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
LIMIT 10
FORMAT PrettyCompact"

結果:

┌─complaint_begin─────┐
│ 07/29/2010 00:01:00 │
│ 12/01/2011 12:00:00 │
│ 04/01/2017 15:00:00 │
│ 03/26/2018 17:20:00 │
│ 01/01/2019 00:00:00 │
│ 06/14/2019 00:00:00 │
│ 11/29/2021 20:00:00 │
│ 12/04/2021 00:35:00 │
│ 12/05/2021 12:50:00 │
│ 12/07/2021 20:30:00 │
└─────────────────────┘

日時文字列をDateTime64型に変換する

ガイドの早い段階で、TSVファイル内に1970年1月1日以前の日付が存在することが判明したため、日付には64ビットDateTime型が必要です。また、日付はMM/DD/YYYYからYYYY/MM/DD形式に変換する必要があります。これらはすべてparseDateTime64BestEffort()で処理できます。

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"WITH (CMPLNT_FR_DT || ' ' || CMPLNT_FR_TM) AS CMPLNT_START,
(CMPLNT_TO_DT || ' ' || CMPLNT_TO_TM) AS CMPLNT_END
select parseDateTime64BestEffort(CMPLNT_START) AS complaint_begin,
parseDateTime64BestEffortOrNull(CMPLNT_END) AS complaint_end
FROM file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
ORDER BY complaint_begin ASC
LIMIT 25
FORMAT PrettyCompact"

上記の2行目と3行目には、前のステップでの連結があります。4行目と5行目でStringDateTime64に解析します。苦情の終了時間が存在するとは限らないため、parseDateTime64BestEffortOrNullを使用しています。

結果:

┌─────────complaint_begin─┬───────────complaint_end─┐
│ 1925-01-01 10:00:00.000 │ 2021-02-12 09:30:00.000 │
│ 1925-01-01 11:37:00.000 │ 2022-01-16 11:49:00.000 │
│ 1925-01-01 15:00:00.000 │ 2021-12-31 00:00:00.000 │
│ 1925-01-01 15:00:00.000 │ 2022-02-02 22:00:00.000 │
│ 1925-01-01 19:00:00.000 │ 2022-04-14 05:00:00.000 │
│ 1955-09-01 19:55:00.000 │ 2022-08-01 00:45:00.000 │
│ 1972-03-17 11:40:00.000 │ 2022-03-17 11:43:00.000 │
│ 1972-05-23 22:00:00.000 │ 2022-05-24 09:00:00.000 │
│ 1972-05-30 23:37:00.000 │ 2022-05-30 23:50:00.000 │
│ 1972-07-04 02:17:00.000 │ ᴺᵁᴸᴸ │
│ 1973-01-01 00:00:00.000 │ ᴺᵁᴸᴸ │
│ 1975-01-01 00:00:00.000 │ ᴺᵁᴸᴸ │
│ 1976-11-05 00:01:00.000 │ 1988-10-05 23:59:00.000 │
│ 1977-01-01 00:00:00.000 │ 1977-01-01 23:59:00.000 │
│ 1977-12-20 00:01:00.000 │ ᴺᵁᴸᴸ │
│ 1981-01-01 00:01:00.000 │ ᴺᵁᴸᴸ │
│ 1981-08-14 00:00:00.000 │ 1987-08-13 23:59:00.000 │
│ 1983-01-07 00:00:00.000 │ 1990-01-06 00:00:00.000 │
│ 1984-01-01 00:01:00.000 │ 1984-12-31 23:59:00.000 │
│ 1985-01-01 12:00:00.000 │ 1987-12-31 15:00:00.000 │
│ 1985-01-11 09:00:00.000 │ 1985-12-31 12:00:00.000 │
│ 1986-03-16 00:05:00.000 │ 2022-03-16 00:45:00.000 │
│ 1987-01-07 00:00:00.000 │ 1987-01-09 00:00:00.000 │
│ 1988-04-03 18:30:00.000 │ 2022-08-03 09:45:00.000 │
│ 1988-07-29 12:00:00.000 │ 1990-07-27 22:00:00.000 │
└─────────────────────────┴─────────────────────────┘
Note

上記の1925年はデータ中のエラーに由来します。オリジナルデータには、1019年から1022年の日付のまま入力された数件のレコードが含まれており、これらは2019年から2022年であるべきです。これらは64ビットDateTime型の最初の日である1925年1月1日として格納されています。

テーブルを作成する

フィールドに対するデータ型の変更に関する前の決定を以下のテーブルスキーマに反映します。また、テーブルのORDER BYPRIMARY KEYを決定します。少なくとも1つのORDER BYまたはPRIMARY KEYを指定する必要があります。このドキュメントの最後にある次のステップセクションで、コラムをORDER BYに含めるためのガイドラインと、より詳しい情報が提供されています。

Order ByとPrimary Keyの句

  • ORDER BYタプルにはクエリフィルタに使用されるフィールドを含めるべきです
  • ディスクでの圧縮を最大化するため、ORDER BYタプルはカーディナリティの昇順にするべきです
  • PRIMARY KEYタプルが存在する場合は、ORDER BYタプルの部分集合でなければなりません
  • ORDER BYが指定されている場合、同じタプルがPRIMARY KEYとして使用されます
  • PRIMARY KEYインデックスは指定されているPRIMARY KEYタプルを用いて作成されるか、ORDER BYタプルを用いて作成されます
  • PRIMARY KEYインデックスはメインメモリに保持されます

データセットを見て、ニューヨーク市の5区における時間経過に応じた報告された犯罪の種類を調べることに決めたと仮定します。これらのフィールドをORDER BYに含めることになります。

カラムデータ辞書の説明
OFNS_DESCキーコードに対応する犯罪の説明
RPT_DT警察に報告された日
BORO_NM発生場所の地区名

TSVファイルをクエリして3つの候補カラムのカーディナリティを確認します:

clickhouse-local --input_format_max_rows_to_read_for_schema_inference=2000 \
--query \
"select formatReadableQuantity(uniq(OFNS_DESC)) as cardinality_OFNS_DESC,
formatReadableQuantity(uniq(RPT_DT)) as cardinality_RPT_DT,
formatReadableQuantity(uniq(BORO_NM)) as cardinality_BORO_NM
FROM
file('${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv', 'TSVWithNames')
FORMAT PrettyCompact"

結果:

┌─cardinality_OFNS_DESC─┬─cardinality_RPT_DT─┬─cardinality_BORO_NM─┐
│ 60.00 │ 306.00 │ 6.00 │
└───────────────────────┴────────────────────┴─────────────────────┘

カードリナリティを考慮すると、ORDER BYは次のようになります:

ORDER BY ( BORO_NM, OFNS_DESC, RPT_DT )
Note

ここでは読みやすいカラム名を使用しており、上記の名前は次のようにマッピングされます。

ORDER BY ( borough, offense_description, date_reported )

データ型の変更とORDER BYタプルを合わせたテーブル構造は以下の通りです:

CREATE TABLE NYPD_Complaint (
complaint_number String,
precinct UInt8,
borough LowCardinality(String),
complaint_begin DateTime64(0,'America/New_York'),
complaint_end DateTime64(0,'America/New_York'),
was_crime_completed String,
housing_authority String,
housing_level_code UInt32,
jurisdiction_code UInt8,
jurisdiction LowCardinality(String),
offense_code UInt8,
offense_level LowCardinality(String),
location_descriptor LowCardinality(String),
offense_description LowCardinality(String),
park_name LowCardinality(String),
patrol_borough LowCardinality(String),
PD_CD UInt16,
PD_DESC String,
location_type LowCardinality(String),
date_reported Date,
transit_station LowCardinality(String),
suspect_age_group LowCardinality(String),
suspect_race LowCardinality(String),
suspect_sex LowCardinality(String),
transit_district UInt8,
victim_age_group LowCardinality(String),
victim_race LowCardinality(String),
victim_sex LowCardinality(String),
NY_x_coordinate UInt32,
NY_y_coordinate UInt32,
Latitude Float64,
Longitude Float64
) ENGINE = MergeTree
ORDER BY ( borough, offense_description, date_reported )

テーブルの主キーを見つける

ClickHouseのsystemデータベース、特にsystem.tableには、今作成したテーブルに関するすべての情報が含まれています。このクエリはORDER BY(ソートキー)とPRIMARY KEYを表示します。

SELECT
partition_key,
sorting_key,
primary_key,
table
FROM system.tables
WHERE table = 'NYPD_Complaint'
FORMAT Vertical

レスポンス:

Query id: 6a5b10bf-9333-4090-b36e-c7f08b1d9e01

Row 1:
──────
partition_key:
sorting_key: borough, offense_description, date_reported
primary_key: borough, offense_description, date_reported
table: NYPD_Complaint

1 row in set. Elapsed: 0.001 sec.

データの前処理とインポート

データ前処理にclickhouse-localツールを使用し、アップロードにはclickhouse-clientを使います。

使用するclickhouse-local引数

Tip

clickhouse-localの引数にtable='input'が含まれています。clickhouse-localは提供された入力(cat ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv)を受け取り、テーブルに挿入します。デフォルトではそのテーブル名はtableです。このガイドでは、データフローを明確にするためにテーブル名をinputに設定しています。clickhouse-localへの最終引数はテーブルから選択するクエリ(FROM input)で、これをclickhouse-clientにパイプしてテーブルNYPD_Complaintを入力します。

cat ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv \
| clickhouse-local --table='input' --input-format='TSVWithNames' \
--input_format_max_rows_to_read_for_schema_inference=2000 \
--query "
WITH (CMPLNT_FR_DT || ' ' || CMPLNT_FR_TM) AS CMPLNT_START,
(CMPLNT_TO_DT || ' ' || CMPLNT_TO_TM) AS CMPLNT_END
SELECT
CMPLNT_NUM AS complaint_number,
ADDR_PCT_CD AS precinct,
BORO_NM AS borough,
parseDateTime64BestEffort(CMPLNT_START) AS complaint_begin,
parseDateTime64BestEffortOrNull(CMPLNT_END) AS complaint_end,
CRM_ATPT_CPTD_CD AS was_crime_completed,
HADEVELOPT AS housing_authority_development,
HOUSING_PSA AS housing_level_code,
JURISDICTION_CODE AS jurisdiction_code,
JURIS_DESC AS jurisdiction,
KY_CD AS offense_code,
LAW_CAT_CD AS offense_level,
LOC_OF_OCCUR_DESC AS location_descriptor,
OFNS_DESC AS offense_description,
PARKS_NM AS park_name,
PATROL_BORO AS patrol_borough,
PD_CD,
PD_DESC,
PREM_TYP_DESC AS location_type,
toDate(parseDateTimeBestEffort(RPT_DT)) AS date_reported,
STATION_NAME AS transit_station,
SUSP_AGE_GROUP AS suspect_age_group,
SUSP_RACE AS suspect_race,
SUSP_SEX AS suspect_sex,
TRANSIT_DISTRICT AS transit_district,
VIC_AGE_GROUP AS victim_age_group,
VIC_RACE AS victim_race,
VIC_SEX AS victim_sex,
X_COORD_CD AS NY_x_coordinate,
Y_COORD_CD AS NY_y_coordinate,
Latitude,
Longitude
FROM input" \
| clickhouse-client --query='INSERT INTO NYPD_Complaint FORMAT TSV'

データの検証

Note

データセットは年に一度以上変わりますので、カウントがこのドキュメントと一致しない場合があります。

クエリ:

SELECT count()
FROM NYPD_Complaint

結果:

┌─count()─┐
│ 208993 │
└─────────┘

1 row in set. Elapsed: 0.001 sec.

ClickHouse内のデータセットのサイズは、元のTSVファイルのわずか12%です。元のTSVファイルのサイズとテーブルのサイズを比較します。

クエリ:

SELECT formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'NYPD_Complaint'

結果:

┌─formatReadableSize(total_bytes)─┐
│ 8.63 MiB │
└─────────────────────────────────┘

クエリを実行する

クエリ1. 月ごとの苦情数を比較する

クエリ:

SELECT
dateName('month', date_reported) AS month,
count() AS complaints,
bar(complaints, 0, 50000, 80)
FROM NYPD_Complaint
GROUP BY month
ORDER BY complaints DESC

結果:

Query id: 7fbd4244-b32a-4acf-b1f3-c3aa198e74d9

┌─month─────┬─complaints─┬─bar(count(), 0, 50000, 80)───────────────────────────────┐
│ March │ 34536 │ ███████████████████████████████████████████████████████▎ │
│ May │ 34250 │ ██████████████████████████████████████████████████████▋ │
│ April │ 32541 │ ████████████████████████████████████████████████████ │
│ January │ 30806 │ █████████████████████████████████████████████████▎ │
│ February │ 28118 │ ████████████████████████████████████████████▊ │
│ November │ 7474 │ ███████████▊ │
│ December │ 7223 │ ███████████▌ │
│ October │ 7070 │ ███████████▎ │
│ September │ 6910 │ ███████████ │
│ August │ 6801 │ ██████████▊ │
│ June │ 6779 │ ██████████▋ │
│ July │ 6485 │ ██████████▍ │
└───────────┴────────────┴──────────────────────────────────────────────────────────┘

12 rows in set. Elapsed: 0.006 sec. Processed 208.99 thousand rows, 417.99 KB (37.48 million rows/s., 74.96 MB/s.)

クエリ2. 地区ごとの総苦情数を比較する

クエリ:

SELECT
borough,
count() AS complaints,
bar(complaints, 0, 125000, 60)
FROM NYPD_Complaint
GROUP BY borough
ORDER BY complaints DESC

結果:

Query id: 8cdcdfd4-908f-4be0-99e3-265722a2ab8d

┌─borough───────┬─complaints─┬─bar(count(), 0, 125000, 60)──┐
│ BROOKLYN │ 57947 │ ███████████████████████████▋ │
│ MANHATTAN │ 53025 │ █████████████████████████▍ │
│ QUEENS │ 44875 │ █████████████████████▌ │
│ BRONX │ 44260 │ █████████████████████▏ │
│ STATEN ISLAND │ 8503 │ ████ │
│ (null) │ 383 │ ▏ │
└───────────────┴────────────┴──────────────────────────────┘

6 rows in set. Elapsed: 0.008 sec. Processed 208.99 thousand rows, 209.43 KB (27.14 million rows/s., 27.20 MB/s.)

次のステップ

A Practical Introduction to Sparse Primary Indexes in ClickHouseは、ClickHouseのインデックスが従来のリレーショナルデータベースとどのように異なるか、ClickHouseがスパースなプライマリインデックスをどのように作成し使用するか、そしてインデックスのベストプラクティスについて解説します。