0

What would perform better on a big table ~30million records grouped into 100_000 indexed buckets each having between 1 to 10_000 records?

  1. MySQL's full text index on the entire dataset (presumably there is no way to narrow it down as cannot combine traditional indices with full text indices)

OR

  1. postgresql's levenshtein distance calculated on pre-indexed data?

Would calculating the distance for 10_000 records consume a lot IO or is it an insignificant amount of data? Everyone warns about using this on big data sets but how big is too big in this context?

i.e. pseudo code queries with:

where indexed_bucket_id = "id12345678"
AND text_field fuzzy matches 'input string'
4
  • 1
    What did your tests show?
    – mustaccio
    Commented May 24, 2023 at 15:52
  • Easy: you cannot index such a query using the Levenshtein distance, so it will always be slow. Use pg_trgm and the % operator with a GIN index. Commented May 24, 2023 at 18:00
  • It depends on whether the = delivers more or fewer rows than the text match.
    – Rick James
    Commented May 24, 2023 at 19:32
  • What is the extent of "fuzzy"? Manual: Single letter error, single letter drop, single letter added, adjacent transposition, etc? Linguistic: 'sounds like', etc? Font tolerance: '6' and '8' look a lot alike in some fonts; lookalikes: i vs I vs l vs 1 and 2 vs Z and 5 vs S? I have algorithms for some of these definitions, but no cure for all of then at once.
    – Rick James
    Commented May 26, 2023 at 15:04

1 Answer 1

1

(MySQL:)

I don't think the Optimizer will do "Index merge intersect", which is just what you need. But check this out:

EXPLAIN
SELECT * FROM tbl
    WHERE indexed_bucket_id = "id12345678"
      AND MATCH(text_field) AGAINST ("...");

If you see that phrase in the 'Extra' column, it is good.

If not, then simulate it something like this (assuming PRIMARY KEY(id)):

SELECT tbl.*
    FROM ( SELECT id FROM tbl WHERE indexed_bucket_id = "id12345678" ) ) AS x
    JOIN ( SELECT id FROM tbl WHERE MATCH(text_field) AGAINST ("...") ) AS y
             USING(id)
    JOIN tbl USING(id)

Let me know if this works; I just invented it.

7
  • Ah i don't have the ability to easily try on the real dataset and worried that for anything smaller it might affect the query optimiser. I'm trying to decide the technology to use to replace existing elastic search implementation that does this. Given that I don't only need to be typo tolerant but also be able to write just a few characters inside a bigger data field, i think full text index is probably the way to go anyway. Just worried about the cost of running the index on the whole dataset across all the buckets while in reality nobody ever needs to query data across 2 different buckets Commented May 25, 2023 at 7:51
  • None of MySQL's offerings are really "typo tolerant". Why do you need to get away from ElasticSearch? When MATCH finds 1000 rows, it looks at only 1000 rows and delivers only 1000 to the next test (eg, to filter on bucket). No 30M-row scan. It is probably not practical if it finds 100K rows. What is the likely Match size?
    – Rick James
    Commented May 25, 2023 at 19:38
  • Want to move away because of the operational overhead of running multiple storage systems. As to full text index, I just think it might be a bit wasteful to employ match query to filter 1000 rows out of 30_000_000, or even compare values between buckets and create this gigantic index while actually the bucket_id index reduces the data size by 99.99%. Wouldn't full text index with ngram parser achieve typo tolerance? I feel that this was the whole point of using full text index, otherwise could use regular index to narrow data down and combine it with "like %xyz%" query on the subset Commented May 26, 2023 at 8:25
  • To be typo-tolerant, you need "like %xyz% OR like %xzy% OR like %yxz%" to handle a simple transposition with "y".
    – Rick James
    Commented May 26, 2023 at 15:01
  • yep, but you don't know in advance what the input query is, also there might be other kinds of problems with spelling Commented May 30, 2023 at 8:48

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.