![]() |
Advanced MySQL Question - Retrieving Similar Items Based on Tags - Printable Version +- CodeIgniter Forums (https://forum.codeigniter.com) +-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20) +--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forumdisplay.php?fid=23) +--- Thread: Advanced MySQL Question - Retrieving Similar Items Based on Tags (/showthread.php?tid=28728) Pages:
1
2
|
Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-19-2010 [eluser]danoph[/eluser] I have products on my website and I show similar items based on the tags for those products. The problem is, the larger the database gets the more of a bottleneck query this becomes. Right now it sorts the results by items having the most matching tags as being most relevant. Does anyone know how to fix this query so it is more scalable? Is there an easy fix that I'm not seeing? The query and tag table structures are below: Code: SELECT distinct item_id, count(*) as matches Code: mysql> describe tags; and... Code: mysql> describe item_tags; item_tags indexes: Code: mysql> show indexes from item_tags; The query takes from 1-3 seconds consistently in the codeigniter profiler and ties up system resources while processing. It can really bring our server to a crawl especially with high traffic! Can anyone help? Thanks! Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-19-2010 [eluser]frist44[/eluser] Having you tried removing the 2nd layer of grouping and do the counting in PHP with a foreach or something. I can't imagine the first part (distinct....where in) should take that long. I do a similar thing for searching keywords with 10-12 other where clauses and it's around 0.01 sec for the query. Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-20-2010 [eluser]bretticus[/eluser] Have you tried converting your tables to use InnoDB? Quote:InnoDB has been designed for maximum performance when processing large data volumes. Its CPU efficiency is probably not matched by any other disk-based relational database engine. It is significantly slower for writes but you have a shopping cart, not twitter. ![]() Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-22-2010 [eluser]danoph[/eluser] Thanks for the suggestion bretticus. After converting the item_tags table to InnoDB, the query went from 1-3 seconds to over 15. If InnoDB is faster for large tables, I am guessing I will need to do some tweaking to the database or something, because it is ridiculously slow now! There aren't a lot of good resources on the internet that talk about this stuff when sites and database start getting a lot larger...The best places are sites like these forums where you guys can help. Thanks for that. Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-22-2010 [eluser]danoph[/eluser] @frist44, There are 3.8 million records in the item_tags table. I wouldn't think sorting them in PHP would scale any better than having MySQL do it? It would have to keep a few thousand to a million records in memory before sorting them if the tag is really popular... Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-22-2010 [eluser]fesweb[/eluser] Just found this line on a MySQL optimizing page: "Avoid using IN(...) when selecting on indexed fields, It will kill the performance of SELECT query." Have you tested it by just doing lots of ORs? (tad_id = 12345 OR tag_id = 23456 OR ...) I have no idea if it's faster, but you can find out easily enough. So that's one idea. Another is that you should consider some type of page caching if you are querying 3+ million records for 50 related tags on every product page. That's a lot of relationships no matter how you write the query, so it's no surprise that it's slow. Which brings me to suggestion 3: Is there a way to determine the most important/relevant tags BEFORE you do the query? Of those 50 tags applied to a product, some of them are bound to be more important than others... Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-22-2010 [eluser]danoph[/eluser] Hi @fesweb, Thanks for the suggestions. What page did you see that suggestion about using IN? I would think the indexes do the total opposite and speed up your select queries since it is selecting IDs that are indexed using a binary tree. There really isn't any manipulation of data going on in the first part of the query which tells me that it's probably not the slowest part. After examining the query in mysql, the slowest part of the query by far is the filesorting, which I believe is used when the initial results are grouped and then sorted. I don't really know how to avoid that part, and I don't want to use caching if it's going to provide old data. I thought about doing some kind of caching but there are so many products being added every day that the data would become outdated really quickly, and querying the database again to update all the time brings up this same problem. Also, I wish I could determine relevance of item_tags before querying them, but the only way I can think of is by adding some kind of weight to the items, which I wouldn't want to do either because it wouldn't provide the most accurate results. I've been doing a few days worth of digging because there isn't much documentation on this subject, but there are tons of websites that have working implementations like amazon, ebay, itunes, etc...I don't get it. Any ecommerce store usually has "related" or similar items. You'd think someone would have already figured this out. Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-22-2010 [eluser]danoph[/eluser] The slow part is actually the copying to tmp table...I would assume that's because the result set is so large? Code: mysql> show profile for query 3; Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-23-2010 [eluser]bretticus[/eluser] Yeah, I think amazon throws more machinery at it. They are probably not using PHP or MySQL either. Neither of which seem to scale well. 3.8 million records is A LOT to query against. I know there are some other database engines that automatically optimize large tables (like mongo), but I have nothing noteworthy to share about your problem tonight. I have *heard* postgres handles large tables better than MySQL. Poor suggestion though. Good luck! Advanced MySQL Question - Retrieving Similar Items Based on Tags - El Forum - 03-23-2010 [eluser]fesweb[/eluser] danoph, I found that "don't use IN" bit here. I should have also mentioned this line: "Don't use DISTINCT when you have or could use GROUP BY " Sorry I can't be more help. In the long run, I think you'll have to end up doing some sort of caching. |