Hash-sharded indexes are an implementation of hash partitioning, not hash indexing.
How hash-sharded indexes work
Overview
CockroachDB automatically splits ranges of data in based on and on . To split a range based on load, the system looks for a point in the range that evenly divides incoming traffic. If the range is indexed on a column of data that is sequential in nature (e.g., or a series of increasing, non-repeating ), then all incoming writes to the range will be the last (or first) item in the index and appended to the end of the range. As a result, the system cannot find a point in the range that evenly divides the traffic, and the range cannot benefit from load-based splitting, creating a on the single range. Hash-sharded indexes solve this problem by distributing sequential data across multiple nodes within your cluster, eliminating hotspots. The trade-off to this, however, is a small performance impact on reading sequential data or ranges of data, as it’s not guaranteed that sequentially close values will be on the same node. Hash-sharded indexes contain a , known as a shard column. CockroachDB uses this shard column, as opposed to the sequential column in the index, to control the distribution of values across the index. The shard column is hidden by default but can be seen with .In v21.2 and earlier, hash-sharded indexes create a physical
STORED instead of a virtual computed column. If you are using a hash-sharded index that was created in v21.2 or earlier, the STORED column still exists in your database. When dropping a hash-sharded index that has created a physical shard column, you must include the clause to drop the shard column. Doing so will require a rewrite of the table.Hash-sharded indexes created in v22.1 and later will not , as the shard column isn’t stored. Hash-sharded indexes created prior to v22.1 will backfill if
schema_change_policy is set to backfill, as they use a stored column. If you don’t want CockroachDB to backfill hash-sharded indexes you created prior to v22.1, drop them and recreate them.Shard count
When creating a hash-sharded index, CockroachDB creates a specified number of shards (buckets) within the cluster based on the value of thesql.defaults.default_hash_sharded_index_bucket_count . You can also specify a different bucket_count by passing in an optional storage parameter. See the example below.
For most use cases, no changes to the cluster setting are needed, and hash-sharded indexes can be created with USING HASH instead of USING HASH WITH (bucket_count = n). Changing the cluster setting or storage parameter to a number greater than the number of nodes within that cluster will produce diminishing returns and is not recommended.
A larger number of buckets allows for greater load-balancing and thus greater write throughput. More buckets disadvantages operations that need to scan over the data to fulfill their query; such queries will now need to scan over each bucket and combine the results.
We recommend doing thorough performance testing of your workload with different bucket_counts if the default bucket_count does not satisfy your use case.
Use instead of the
sql.defaults.* . This allows you to set a default value for all users for any that applies during login, making the sql.defaults.* cluster settings redundant.Hash-sharded indexes on partitioned tables
You can create hash-sharded indexes with implicit partitioning under the following scenarios:- The table is partitioned implicitly with , and the
crdb_regioncolumn is not part of the columns in the hash-sharded index. - The table is partitioned implicitly with
PARTITION ALL BY, and the partition columns are not part of the columns in the hash-sharded index. Note thatPARTITION ALL BYis in preview.
PARTITION BY, then that index cannot be hash-sharded. Partitioning columns cannot be placed explicitly as key columns of a hash-sharded index as well, including REGIONAL BY ROW table’s crdb_region column.
Create a hash-sharded index
The general process of creating a hash-sharded index is to add theUSING HASH clause to one of the following statements:
Examples
Create a table with a hash-sharded primary key
Let’s create theproducts table and add a hash-sharded primary key on the ts column:
Create a table with a hash-sharded secondary index
Let’s now create theevents table and add a secondary index on the ts column in a single statement:
Create a hash-sharded secondary index on an existing table
Let’s assume theevents table already exists:
Alter an existing primary key to use hash sharding
Let’s assume theevents table already exists:
USING HASH clause at the end of the key definition:
Show hash-sharded index in SHOW CREATE TABLE
Following the above example, you can show the hash-sharded index definition along with the table creation statement using SHOW CREATE TABLE:
Create a hash-sharded secondary index with a different bucket_count
You can specify a different bucket_count via a storage parameter on a hash-sharded index to optimize either write performance or sequential read performance on a table:

