Background:
Hey I'm using MySQL 5.6.17 InnoDB, I've read on mysql website that FULLTEXT is now avaiable for InnoDB in 5.6+ version. so i don't have to change from InnoDB to MyISAM Here is the link I altered TWO of my table columns for FULLTEXT search by using the following query
ALTER TABLE `es_officers` ADD FULLTEXT Index_officer_name (es_officer_name)
ALTER TABLE `es_officers` ADD FULLTEXT Index_officer_fname (es_officer_fname)
Altered Table Registered in Information Schema:
Then i checked in my information schema if the altered table columns are registered or not by running the following query
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM statistics
WHERE index_type LIKE 'FULLTEXT%'
It showed me exacttly two results which i was expecting
Problem:
when i write a query to MATCH a sting AGAINST two columns it gives me an error
SELECT * FROM `es_officers` WHERE MATCH (es_officer_name, es_officer_fname) AGAINST ('abc')
#1191 - Can't find FULLTEXT index matching the column list
BUT:
when i try to query the columns separately like below it works absolutely fine
SELECT * FROM `es_officers` WHERE MATCH (es_officer_name) AGAINST ('abc')
SELECT * FROM `es_officers` WHERE MATCH (es_officer_fname) AGAINST ('abc')
I don't know what is it I'm doing wrong, help is highly appreciated.
Multiples issues:
You have two separate fulltext indexes, each covering a single field. You have WHERE MATCH (es_officer_name, es_officer_fname) as your query, which requires a SINGLE index covering both fields. MySQL will not use two separate indexes for this query - it can't. that's not how fulltext indexing works. You need an alter ... fulltext (es_officer_name, es_officer_fname) instead added.
And even then, abc will fall under the default minimum word length and won't get indexed.
Besides, you can try something like:
SELECT * FROM es_officers
WHERE MATCH es_officer_name AGAINST ('abc') + MATCH es_officer_fname AGAINST ('abc')
Though, as Marc B said, 'abc' value is too short.
Related
I have a table with different fields, in particular name (varchar 255), surname (varchar 255), but actually I used them as name (varchar 90) and surname (varchar 70), considering the maxlength limit.
This table has ~620,000 rows and I'm doing a lot of queries like the following one:
SELECT * FROM table WHERE name LIKE "%word1%" AND surname LIKE "%word2%"
I've added FULLTEXT indexes on both field (tried also one index contains both fields), but the performance is slower than queries without any index.
What I missing?
Thanks in advance
Edit:
Following your replies, I show you some results.
Case A.
Table without any index
Query:
SELECT *
FROM `table`
WHERE `name` LIKE '%word1%'
AND `surname` LIKE '%word2%'
executed two times was solved in 0.8870 and 0.8952 sec
Case B.
I've added a FULLTEXT index on name and a FULLTEXT index on surname.
Query
SELECT *
FROM table
WHERE match(name) AGAINST ('+word1*' in boolean mode)
AND match(surname) AGAINST ('+word2*' in boolean mode)
executed two times was solved in 0.9647 and 1.0380 sec
Note: table has InnoDB engine and unfortunatly MySQL is older than 5.6; I cannot convert easily from InnoDB to MyISAM because of foreign keys.
Other ideas?
Thanks again
It will be better if you use Mysql (InnoDB)'s Full text search in boolean mode.
More Details here
Fulltext search is designed to be efficient in cases like yours and is considerably faster than full scan.
A fulltext search query for your case might look like this :
SELECT * FROM table WHERE match(name) against ('+word1*' in boolean mode) AND match(surname) against ('+word2*' in boolean mode);
"cannot convert easily" -- Sure you can. Make a MyISAM table with nothing but the text column(s) and the id. Then do the MATCH..AGAINST using that table and JOIN (without FKs) to the InnoDB table. The id is already the PRIMARY KEY of the other table, correct? The JOIN just needs an index; the PK qualifies as such; no FK is required.
You do have a 2-column FULLTEXT index, correct? FULLTEXT(name, surname)
I have a table with 150k rows of data, and I have column with a UNIQUE INDEX, It has a type of VARCHAR(10) and stores 10 digit account numbers.
Now whenever I query, like a simple one:
SELECT * FROM table WHERE account_number LIKE '0103%'
It results 30,000+ ROWS, and when I run a EXPLAIN on my query It shows no INDEX is used.
But when I do:
SELECT * FROM table WHERE account_number LIKE '0104%'
It results 4,000+ ROWS, with the INDEX used.
Anyone can explain this?
I'm using MySQL 5.7 Percona XtraDB.
30k+/150k > 20% and I guess it is faster to do table scan. From 8.2.1.19 Avoiding Full Table Scans:
The output from EXPLAIN shows ALL in the type column when MySQL uses a full table scan to resolve a query. This usually happens under the following conditions:
You are using a key with low cardinality (many rows match the key value) through another column. In this case, MySQL assumes that by using the key it probably will do many key lookups and that a table scan would be faster.
If you don't need all values try to use:
SELECT account_number FROM table WHERE account_number LIKE '0103%'
instead of SELECT *. Then your index will become covering index and optimizer should always use it (as long as WHERE condition is SARGable).
The most database uses B tree for indexing. In this case the database optimizer don't use the index because its faster to scan without index. Like #lad2025 explained.
Your database column is unique and i think your cardinality of your index is high. But since your query using the like filter the database optimizer decides for you to choose not to use the index.
You can use try force index to see the result. Your using varchar with unique index. I would choose another data type or change your index type. If your table only contains numbers change it to numbers. This will help to optimize you query a lot.
In some cases when you have to use like you can use full text index.
If you need help with optimizing your query and table. Provide us more info and which info you want to fetch from your table.
lad2025 is correct. The database is attempting to make an intelligent optimization.
Benchmark with:
SELECT * FROM table FORCE INDEX(table_index) WHERE account_number LIKE '0103%'
and see who is smarter :-) You can always try your hand at questioning the optimizer. That's what index hints are for...
https://dev.mysql.com/doc/refman/5.7/en/index-hints.html
I am creating a mysql fulltext search engine for my website, and I have an advanced search page that allows the user to limit which columns they would like to search under. However, whenever I make a fulltext search index, all the columns used in that index must be used or else I get an error message. Is there any way to make a mysql index for fulltext where I can use just some of the columns?
For example I have 5 columns in my index, made by this statement:
ALTER TABLE table1 ADD FULLTEXT fulltext_index(subject, course, prof, semester,
year);
If I wanted to search under only subject and course, I would get the error:
#1191 - Can't find FULLTEXT index matching the column list
You just need to create more indexes for each possible combination you want to search:
alter table table1 add fulltext fulltext_index2(subject,course);
alter table table1 add fulltext fulltext_index3(course,semester,year);
Etc...see if that solves the issue.
No, a fulltext index requires you to use all of the columns. If you want to use only some of them, you'll need a separate fulltext index for every permutation. I haven't tested it, but you MAY get around it by using only columns in the order specified. e.g. an index on columns (a,b,c) might allow you to search only (a,b) because they're listed first, but not (a,c) or (b,c).
I'm trying to set up a FULLTEXT index in an existing db table (with like 50k records), with the command below, which worked:
ALTER TABLE `record_attributes` ADD FULLTEXT `FULLTEXT` (`content_text` ,`content_varchar`)
Problem is, when I try to do a MATCH AGAINST on that table, it gives me this error:
#1191 - Can't find FULLTEXT index matching the column list
I've been searching on google and didn't find anything that I could be doing wrong. Does the index have to be added on tables without any records?
Cheers
If you search by 1 column, fulltext index by 2 columns is not matching.
I have already posted a question about this, but the situation has changed sufficiently to warrant a new one.
I have a MySQL table called aromaProducts in which there are 7 columns with the FULLTEXT index, and which has three records in it. When I make a query against it like:
SELECT * FROM aromaProducts WHERE MATCH (title) AGAINST ('chamomile');
I get the correct result. However, when I try adding a second field to search in, I get an error:
Can't find FULLTEXT index matching the column list
Every column on its own works fine. I have also explicitly adding WITH QUERY EXPANSION and the same thing.
I have another table, aromaProducts1, and instead of assigning FULLTEXT to the fields one at a time, I assigned it to all 7 at the moment of table creation. Against this table, no queries work. When examining the table structure, the difference is this:
The first table shows each field having its own FULLTEXT index, while the second has one index, named title (the first field to have it assigned), and it applies to all seven fields.
All columns that I have made FULLTEXT are either VARCHAR or TEXT datatypes. I have no clue what the problem is.
You have to create the fulltext index on all columns you are going to match
If you want to match on (col1,col2,col3) you have to create fulltext index on col1,col2 and col3. If you want to match on(col1,col2) you have to implement another fulltext index(on col1 and col2), you can't use that one on col1, col2 and col3
you have to create one fulltext index with several columns, not one for each