How to Set Up ProxySQL Sharding

ProxySQL supports three primary sharding approaches: user-based, schema-based, and data-based. Choose the approach that best fits your application architecture.

Option 1: User-Based Sharding

The simplest approach — queries are routed based on which user connects. No query rules are needed.

INSERT INTO mysql_users (username, password, active, default_hostgroup, comment)
VALUES
  ('accounts',     'shard0_pass', 1, 0, 'Routed to the accounts shard'),
  ('transactions', 'shard1_pass', 1, 1, 'Routed to the transactions shard'),
  ('logging',      'shard2_pass', 1, 2, 'Routed to the logging shard');

LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

Application mapping:

App ModuleShard UserHostgroup
CRMaccounts0
OLTPtransactions1
Log Managerlogging2

Option 2: Schema-Based Sharding

Map schema names to destination hostgroups via query rules. Assumes schemas follow a naming convention such as shard_0, shard_1, etc.

INSERT INTO mysql_query_rules (rule_id, active, schemaname, destination_hostgroup, apply)
VALUES
  (1, 1, 'shard_0', 0, 1),
  (2, 1, 'shard_1', 1, 1),
  (3, 1, 'shard_2', 2, 1);

LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

Option 3: Data-Based Sharding

The most flexible approach — routes specific rows (identified by a shard key) to different hostgroups. Requires careful rule design but allows sharding at the table or row level.

Example Schema

loc_account_data table:
+----------------------------------------+---------+---------+
| loc_id                                 | user    | acc_id  |
+----------------------------------------+---------+---------+
| 20086020554955909836090724037181646035 | joe32   | 1       |
| 21503957780049285539986052866765125704 | sam57   | 2       |
| 75863560943999160082133817802533222835 | pam18   | 3       |
+----------------------------------------+---------+---------+

loc_mapping table:
+----------------------------------------+---------+
| loc_id                                 | region  |
+----------------------------------------+---------+
| 20086020554955909836090724037181646035 | AMERICA |
| 21503957780049285539986052866765125704 | EMEA    |
| 75863560943999160082133817802533222835 | OCEANIA |
+----------------------------------------+---------+

INSERT Rules

INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
  (1, 1, 'loc_account_data.*20086020554955909836090724037181646035', 0, 1),
  (2, 1, 'loc_account_data.*21503957780049285539986052866765125704', 1, 1),
  (3, 1, 'loc_account_data.*75863560943999160082133817802533222835', 2, 1);

UPDATE / DELETE / SELECT Rules

Match the shard key directly for all other statement types:

INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
  (4, 1, 'loc_id = 20086020554955909836090724037181646035', 0, 1),
  (5, 1, 'loc_id = 21503957780049285539986052866765125704', 1, 1),
  (6, 1, 'loc_id = 75863560943999160082133817802533222835', 2, 1);

LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

Considerations

  • User and schema sharding are simpler to implement and maintain — prefer these where possible
  • Data-based sharding requires a rule for every shard key value and every statement type (INSERT, UPDATE, DELETE, SELECT)
  • Cross-shard joins must be handled at the application level — ProxySQL routes to a single hostgroup per query
  • Data-based sharding can be combined with read/write split by adding additional rules per shard
  • Sharding is not limited to these three methods — they are the most common patterns