2010-03-09 120 views
0

我有一个MySQL数据库,其中包含产品所在的相当大的表。他们每个人都有自己的id和categoryId字段,其中有一个类别id属于该产品。现在我有一个从给定的类别,如翻出产品查询:使用IN运算符优化MySQL查询

SELECT * FROM products WHERE categoryId IN (1, 2, 3, 4, 5, 34, 6, 7, 8, 9, 10, 11, 12) 

当然,来了一个WHERE子句和ORDER BY排序而不是在这件事情。假设这些产品是25万,每天的访问量超过10万。在这样的条件下,slow_log表中的这些查询的权重将会占用大量的时间。

你有任何想法如何优化给定的问题?

表引擎是MyISAM。上的categoryId

+0

你确实有'categoryId'上的索引,对吧? – DanMan 2014-06-13 20:30:01

回答

2

指数不会在这种情况下帮助,IN(...)查询会产生序列扫描而不是索引查找反正。

我会首先考虑重新设计系统摆脱多个类别中选择的,如果它是不恰当的,缓存查询结果。

例如,你可以创建一个帮助台items_category_groups(哈希,ITEM_ID)和多个类别的客户端查询后,哈希他们联合标识和查找此表。如果找不到,请进行昂贵的查询并填写此表。如果找到,请联系这些表进行便宜的查询。其他像memcached这样的缓存工具也可以工作。

+0

好主意,但此查询用来翻出产品为特定类别及其子类别(此类别的整支),所以它是IMPOSIBLE – 2010-03-09 10:35:42

+0

然后缓存是我看到的唯一途径,但高速缓存的大小将是大(25万*计数的类别组合),所以我会将它们存储在数据库中,而不是memcache或其他东西。 – Andrey 2010-03-09 11:06:30

+0

如果您只想从一个类别(及其子类别)提取产品,则可以创建一个帮助器表(category_id,item_id),并用所有category_id-item_id对(包括子类别)填充它。这个表格不会很大(比如说,如果你的分类级别为4,它将包含不超过1m *类别的两个int行数,这不是什么大不了的)。然后,您将通过使用索引的单个快速查询来获取产品。 – Andrey 2010-03-09 11:13:33