Using FULLTEXT indexes has to be handled with great care. Why ? While FULLTEXT index searches do work, the MySQL Query optimizer tends to suggest full table scans if you do not express the query properly.
Let's take your query and look for 'tom'
SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink
FROM cast_movie as c JOIN film_info as f ON c.ImdbId = f.ImdbId
WHERE c.castName LIKE '%tom%';
This joins everything. Then, it scans the resulting temp table and returns every row with tom
.
Let's implement the FULLTEXT method
SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink
FROM cast_movie as c JOIN film_info as f ON c.ImdbId = f.ImdbId
WHERE MATCH(c.castName) AGAINST ('+tom' IN BOOLEAN MODE);
I can almost assure you that a full table scan will occur during the join because I have experienced it hundreds of times:
I started writing posts about FULLTEXT and query refactoring ever since I saw a post from webmasterworld.com entitled MySQL Match Against + a very expensive join. How do I optimize this?
Given the information I just mentioned let's take your query and refactor it to handle the FULLTEXT and stilldo a good join.
SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink
FROM cast_movie as c JOIN film_info as f ON c.ImdbId = f.ImdbId
WHERE MATCH(c.castName) AGAINST ('+tom' IN BOOLEAN MODE);
First, apply the MATCH ... AGAINST
operator to cast_movie
and return ImdbId
and other fields
SELECT ImdbId,movieName,castName,movieImdbId FROM cast_movie
WHERE MATCH(c.castName) AGAINST ('+tom' IN BOOLEAN MODE)
Make that a subquery to provide keys to join and retrieve data from film_info
SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink FROM
(
SELECT ImdbId,movieName,castName,movieImdbId FROM cast_movie
WHERE MATCH(c.castName) AGAINST ('+tom' IN BOOLEAN MODE)
) as c JOIN film_info as f ON c.ImdbId = f.ImdbId;
This should produce a better result.
If your tables use InnoDB Storage Engine, remember to tune the InnoDB Fulltext options. Any fulltext option that does not start with innodb_
is meant for MyISAM (See my post MySQL FullText search on string shorter than 3 chars returns no rows)
Give it a Try !!!
Your query has a logical flaw: it tries to find people who are NOT in the list of people who DO have coaching but only if the coaching is NOT in the target window.
Instead, join the employee and coaching table on employee_id, using all rows in employee but only using rows in coaching where the stop_date is later than or equal to the desired start date (coaching ends after the window starts) and the the start_date is less than or equal to the desired stop date (coaching starts before the window ends). Then exclude the employees with one or more matching rows in coaching.
SELECT e.id AS employee_id
FROM employee e
LEFT JOIN coaching c ON c.employee_id = e.id
AND c.end_date >= '2014-12-26'
AND c.start_date <= '2015-01-30'
WHERE c.employee_id IS NULL;
Live demo: http://sqlfiddle.com/#!9/79b39/4
Best Answer
Here is a way to do this. I hope , the join are on the right fields.
The output: