kylex
kylex

Reputation: 14426

Use LIKE and NOT LIKE more efficeinty when testing for spaces

I have the following query:

SELECT * FROM table 
    WHERE tags LIKE '%$search%' 
          AND tags NOT LIKE '% $search%' 
          AND tags NOT LIKE '%$search %'

Basically it's searching for for all terms that match unless there's a space before or after the search term.

So if I searched for "novel", the terms "graphic novel" or "novel romantic" will not show up.

This seems like a costly query, so I was wondering if there is a more efficient way to do this. Thanks!

Upvotes: 1

Views: 58

Answers (2)

Shlomi Noach
Shlomi Noach

Reputation: 9394

A regular expression match will make the query shorter )prettier is a matter of the observer), but most definitely not more efficient.

Looking at your comment to Sashi Kant, am I right do deduce the text on which you are searching is a comma delimited set of attributes? You wrote: big,novel,graphic novel. Is it always like that?

If so, then, again, still not efficient but nevertheless easier to manage, is to write

SELECT * FROM table 
  WHERE FIND_IN_SET('novel', tags) > 0

What's shared between your solution, a regex solution and the FIND_IN_SET solution is that neither can utilize any index on the tags column. All queries are using some sort of function over the column, and that negates the usage af an index.

If you want performance, and data format is as I think it is, then you may want to normalize the table. Create a new table like known_tag:

CREATE TABLE known_tag (
  known_tag_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(127) CHARSET ascii
);

(pick your own data types)

And then a many-to-many connecting table, like:

CREATE TABLE original_table_to_known_tag (
  original_table_id INT UNSIGNED,
  known_tag_id INT UNSIGNED,
  PRIMARY KEY(original_table_id, known_tag_id),
  KEY(known_tag_id)
);

And finally, work your query like this:

SELECT 
  table.*
FROM 
  known_tag 
  JOIN original_table_to_known_tag USING (known_tag_id)
  JOIN original_table USING (original_table_id)
WHERE
  known_tag.name = 'novel'
;

This type of query will use the proper indexes and be more efficient on large tables.

Upvotes: 1

Adriaan Stander
Adriaan Stander

Reputation: 166476

Have a look at using 12.5.2. Regular Expressions

Upvotes: 0

Related Questions