2010-03-09 47 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