I have a posts table with a JSON column of an array with IDs. This column’s data looks exactly like:
[1, 3, 17, 19]
These values are not quoted.
To check if a user should see a post, I simply use JSON_CONTAINS(userlist, '(the user ID)', '$')
. However, after many thousands of posts, this is starting to get too slow. I’d like to avoid normalizing this to another table with proper relations for now, so I’m wondering what’s the best way to see if a user ID exists in a field like what I have.
Note: this is not exactly a duplicate. My values are straight integers, which is why I seemingly can’t use JSON_SEARCH()
?
2
Answers
You really should bite the bullet and normalise, as this operation is only going to get slower. In the meantime, there are a couple of ways you can do this with string operations using
LIKE
andREGEXP
:In both cases for your sample data the output is:
Using
LIKE
will probably be faster thanJSON_CONTAINS
, but usingREGEXP
probably won’t. You’d need to benchmark on your server.If you’re using MySQL 8+, then you can use
JSON_TABLE
:Again, performance will be dependent on your server.
Demo on db-fiddle
Demo of the MySQL 8.0 multi-valued index:
It’s true that
JSON_SEARCH()
doesn’t work with integer values, but the multi-valued index I defined in the example is indexing integer values, so this works.Of course the whole task would be simpler if you normalized your table instead of using a JSON array. JSON generally makes queries and optimization harder.