英文:
How can I retrieve all rows from a JSON array that match a specific country ID?
问题
I have a table named TEST_TABLE in my MySQL database. This table contains a column called COUNTRIES_IDS, which has a data type of json. I used a json array because MySQL does not support multiple foreign keys on the same column. However, I am not sure if this is the most optimal approach, and if there is a better alternative.
Currently, there are 1,348,193
rows in this table.
Here is how the table looks:
CREATE TABLE TEST_TABLE (
ID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
COUNTRIES_IDS JSON NULL
) ENGINE = INNODB DEFAULT CHARSET = UTF8 COLLATE = UTF8_UNICODE_CI;
Here is the data that is inside the table:
ID | COUNTRIES_IDS |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
2 | [39, 30, 6] |
3 | [20, 38, 35, 13, 32, 31, 2, 47, 46, 24, 1, 5, 9] |
4 | [7] |
5 | [14, 22, 15, 30, 36, 20] |
Etc to 1,348,193 rows | Etc to 1,348,193 rows |
The expected output of the query should be like this:
ID | COUNTRIES_IDS |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
5 | [14, 22, 15, 30, 36, 20] |
... | ... |
My requirements are as follows:
- How can I fetch all the rows that contain country ID 15?
- How can I optimize the query to retrieve results faster without having to read all 1,348,193 rows, as this would significantly slow down the query?
英文:
I have a table named TEST_TABLE in my MySQL database. This table contains a column called COUNTRIES_IDS, which has a data type of json. I used a json array because MySQL does not support multiple foreign keys on the same column. However, I am not sure if this is the most optimal approach, and if there is a better alternative.
Currently, there are 1,348,193
rows in this table.
Here is how the table looks:
CREATE TABLE TEST_TABLE (
ID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
COUNTRIES_IDS JSON NULL
) ENGINE = INNODB DEFAULT CHARSET = UTF8 COLLATE = UTF8_UNICODE_CI;
Here is the data that is inside the table:
ID | COUNTRIES_IDS |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
2 | [39, 30, 6] |
3 | [20, 38, 35, 13, 32, 31, 2, 47, 46, 24, 1, 5, 9] |
4 | [7] |
5 | [14, 22, 15, 30, 36, 20] |
Etc to 1,348,193 rows | Etc to 1,348,193 rows |
The expected output of the query should be like this:
ID | COUNTRIES_IDS |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
5 | [14, 22, 15, 30, 36, 20] |
... | ... |
My requirements are as follows:
- How can I fetch all the rows that contain country ID 15?
- How can I optimize the query to retrieve results faster without having to read all 1,348,193 rows, as this would significantly slow down the query?
答案1
得分: 2
CREATE TABLE test (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
countries_ids JSON NULL,
INDEX idx_countries_ids ((CAST(countries_ids AS UNSIGNED ARRAY)))
) ENGINE = INNODB DEFAULT CHARSET = UTF8 COLLATE = UTF8_UNICODE_CI;
INSERT INTO test VALUES
(1, '[41, 9, 38, 15, 22, 5, 7, 32]'),
(2, '[39, 30, 6]'),
(3, '[20, 38, 35, 13, 32, 31, 2, 47, 46, 24, 1, 5, 9]'),
(4, '[7]'),
(5, '[14, 22, 15, 30, 36, 20]');
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE JSON_CONTAINS(countries_ids, '[15]');
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE JSON_OVERLAPS(countries_ids, '[15]');
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE 15 MEMBER OF (countries_ids);
EXPLAIN
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE 15 MEMBER OF (countries_ids);
See: Functions That Search JSON Values, Multi-Valued Indexes
英文:
CREATE TABLE test (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
countries_ids JSON NULL,
-- create an index which will improve searching queries
INDEX idx_countries_ids ((CAST(countries_ids AS UNSIGNED ARRAY)))
) ENGINE = INNODB DEFAULT CHARSET = UTF8 COLLATE = UTF8_UNICODE_CI;
INSERT INTO test VALUES
(1, '[41, 9, 38, 15, 22, 5, 7, 32]'),
(2, '[39, 30, 6]'),
(3, '[20, 38, 35, 13, 32, 31, 2, 47, 46, 24, 1, 5, 9]'),
(4, '[7]'),
(5, '[14, 22, 15, 30, 36, 20]');
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE JSON_CONTAINS(countries_ids, '[15]')
id | CAST(countries_ids AS CHAR) |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
5 | [14, 22, 15, 30, 36, 20] |
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE JSON_OVERLAPS(countries_ids, '[15]')
id | CAST(countries_ids AS CHAR) |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
5 | [14, 22, 15, 30, 36, 20] |
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE 15 MEMBER OF (countries_ids)
id | CAST(countries_ids AS CHAR) |
---|---|
1 | [41, 9, 38, 15, 22, 5, 7, 32] |
5 | [14, 22, 15, 30, 36, 20] |
EXPLAIN -- an example which shows that the index is used in the query execution
SELECT id, CAST(countries_ids AS CHAR)
FROM test
WHERE 15 MEMBER OF (countries_ids)
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | test | null | ref | idx_countries_ids | idx_countries_ids | 9 | const | 2 | 100.00 | Using where |
See: Functions That Search JSON Values, Multi-Valued Indexes
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论