I have a Product table with a fulltext index on the name field and the description field. I want to do a select for products that match text with the name being more important than the description - hence the order by clause. They also need to fit into certain categories. I also only want to show Products that have an offer in the Offers table.
The Product table has over 500 000 rows and the ProductCategory has the same number of rows which just maps the Products to a Category.
Here is what I’ve tried, but the number of rows scanned is far too much, and I can’t think of any other info to make an index on.
SELECT DISTINCT p.id, MATCH (p.name) AGAINST (‘the colour purple’) AS name_score, MATCH (p.description) AGAINST (‘the colour purple’) AS description_score
FROM Product as p
INNER JOIN ProductCategory as pc on p.id=pc.product_id
INNER JOIN Category as c on c.id=pc.category_id
WHERE ( pc.category_id=‘1’
OR pc.category_id IN ( ‘18’ , ‘20’ , ‘21’ , ‘22’ , ‘23’ , ‘24’ , ‘25’ , ‘26’ , ‘27’ , ‘28’ , ‘29’ , ‘30’ , ‘31’ , ‘32’ , ‘33’ , ‘34’ , ‘35’ , ‘36’ , ‘37’ , ‘38’ , ‘39’ , ‘40’ , ‘41’ , ‘42’ , ‘43’ , ‘44’ , ‘45’ , ‘46’ , ‘47’ , ‘48’ , ‘49’ , ‘50’ , ‘51’ , ‘52’ , ‘53’ , ‘54’ , ‘55’ , ‘56’ , ‘57’ , ‘58’ , ‘59’ , ‘60’ , ‘61’ , ‘62’ , ‘63’ , ‘64’ , ‘65’ , ‘66’ , ‘67’ , ‘19’ , ‘68’ , ‘69’ , ‘70’ , ‘71’ , ‘72’ , ‘73’ , ‘74’ , ‘821’ , ‘822’ )
)
AND ( (
(MATCH (p.name) AGAINST (‘the colour purple’))
OR (MATCH (p.description) AGAINST (‘the colour purple’))
)
)
AND p.id IN (
SELECT product_id
FROM Offer AS o
WHERE o.price > 0
AND o.deleted = 0
)
AND p.needs_verification=0
ORDER BY name_score DESC, description_score DESC
LIMIT 0, 20;
±—±-------------------±------±---------------±------- --------------------±-------------------±--------±------- ----------------------------±-------±--------------------- ------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±-------------------±------±---------------±------- --------------------±-------------------±--------±------- ----------------------------±-------±--------------------- ------------------------+
| 1 | PRIMARY | p | ref | PRIMARY,needs_verification | needs_verification | 1 | const | 463119 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | pc | eq_ref | product_id,category_id | product_id | 3 | priceche_pricecheck.p.id | 1 | Using where; Distinct |
| 1 | PRIMARY | c | eq_ref | PRIMARY | PRIMARY | 3 | priceche_pricecheck.pc.category_id | 1 | Using index; Distinct |
| 2 | DEPENDENT SUBQUERY | o | index_subquery | product_id,price,deleted | product_id | 3 | func | 2 | Using index; Using where |
±—±-------------------±------±---------------±------- --------------------±-------------------±--------±------- ----------------------------±-------±--------------------- ------------------------+