0

I have a very simple table with 100,000 rows.

CREATE TABLE test_database.products (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `city_id` int  NOT NULL,
  `market_id` int NOT NULL,
  `product_id` int NOT NULL,
  `search` varchar(450) COLLATE utf8mb4_unicode_ci NOT NULL,
  `quantity` int NOT NULL,
  `price` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL,
   PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

I added fulltext:

ALTER TABLE products ADD fulltext (search);

And when I search:

    SELECT 
        id, market_id, product_id, quantity, price,
        MATCH(pr.search) AGAINST('dolor* qui*' IN BOOLEAN MODE) as srv 
    from 
        products pr 
    where 
        pr.city_id = 1 and
        MATCH(pr.search) AGAINST('dolor* qui*' IN BOOLEAN MODE) 
    ORDER by
        srv DESC;

It takes ~ 2500 ms.

Explain select ...

id|select_type|table|partitions|type    |possible_keys|key   |key_len|ref  |rows|filtered|Extra                        |
--|-----------|-----|----------|--------|-------------|------|-------|-----|----|--------|-----------------------------|
 1|SIMPLE     |pr   |          |fulltext|search       |search|0      |const|   1|    10.0|Using where; Ft_hints: sorted|

MySQL version:

 Ver 8.0.21 for Win64 on x86_64

What I'm doing wrong?

9
  • Please provide EXPLAIN SELECT ... . What version of MySQL? How many rows in the resultset?
    – Rick James
    Commented Aug 24, 2020 at 22:35
  • You are looking for either dolor* or qui*, correct? Perhaps you would prefer "and"? AGAINST('+dolor* +qui*' in boolean mode) ?
    – Rick James
    Commented Aug 24, 2020 at 22:37
  • I don't get what you mean in the last comment. I'm looking for both or at least one of them.
    – sdeav
    Commented Aug 24, 2020 at 22:50
  • OK, ignore my OR vs AND. Meanwhile, how many rows does it return?
    – Rick James
    Commented Aug 24, 2020 at 22:56
  • My app sets limit 200 rows. So it returns 200 rows. But, when I'm using count(*) it counts 8545 rows.
    – sdeav
    Commented Aug 24, 2020 at 23:08

2 Answers 2

1

Give this formulation a try:

SELECT ..., x.relevance
    FROM (
        SELECT  id,
                MATCH(...) AGAINST(...) AS relevance
            FROM products 
            WHERE MATCH(...) AGAINST(...)
         ) AS x
    JOIN products AS pr  USING(id)
    WHERE pr.city_id = 1
    ORDER BY x.relevance DESC
3
  • this one takes 11892 ms. My selection works perfectly with MyISAM and in NATURAL LANGUAGE mode. Like ~ 55 ms
    – sdeav
    Commented Aug 24, 2020 at 23:36
  • 1
    File a bug report at bugs.mysql.com
    – Rick James
    Commented Aug 24, 2020 at 23:43
  • Got it, thank you.
    – sdeav
    Commented Aug 24, 2020 at 23:50
0

You are trying to run match twice, also you have to specify which score you want to have, which means how good the match should be.

Se if a score bigger as 0.5 helps else try a lower number

Also you should look at https://dev.mysql.com/doc/refman/8.0/en/fulltext-boolean.html it explains a lot about Boolean seraches

SELECT 
    id, market_id, product_id, quantity, price,
    MATCH(pr.search) AGAINST('dolor* qui*' IN BOOLEAN MODE) as srv 
from 
    products pr 
where 
    pr.city_id = 1 
HAVING srv > 0.5
ORDER by
    srv DESC
;
7
  • Thank you. But now it takes 1500 ms. Which is still too slow.
    – sdeav
    Commented Aug 24, 2020 at 21:30
  • 1,5 seconds is quote fast and as you can see here makandracards.com/makandra/… the performance isn#t good with big databases. if you really want ti get quicker and don't fear soe work look for elasticsearch.
    – nbk
    Commented Aug 24, 2020 at 21:43
  • My rows will be maximum 0,5 million. I don't think I should mess up with elasticsearch for that. But still, 1500 is not fast enough for 100,000 rows...
    – sdeav
    Commented Aug 24, 2020 at 21:47
  • then you should try faster hardware also yu didn't wrote which mysql version you are using
    – nbk
    Commented Aug 24, 2020 at 22:01
  • Latest available version. And I remember that I have searched even with 0,5 million rows with this hardware. But, I forgot how I did that..
    – sdeav
    Commented Aug 24, 2020 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.