Question

I'm writing a multistore webshop application in PHP/MYSQL. The products table has about a million records, currently i'm having 5 stores with all products in it and about 3 stores with a few products. The product's price sometimes varies from store to store. Because it should be possible to add or delete certain products for let's say only shop 2, i created a junction table. My tables looks like this:

products(id,name,description,price,media) ~1M records
stores(id,name)
products_stores(id,product_id,store_id,price) ~5M records

When searching for products the query takes about 20 seconds. I added indices to products(name,description) + products_stores(product_id,store_id). Is there any way I could speed up the process? Most of the records in products_stores are the same (except for the store_id), but I'd like to keep it flexible.

The query:

SELECT 
  Product.id, 
  Product.name, 
  Product.drager, 
  Product.import, 
  Product.price, 
  Product.description, 
  Product.units 
FROM 
  products AS Product 
INNER JOIN 
  products_stores AS ProductStore ON (
    ProductStore.product_id = Product.id 
    AND 
    ProductStore.store_id =1
  ) 
WHERE 
  name LIKE 'bach%' 
ORDER BY 
  Product.description asc 
LIMIT 
  500

I added a FULLTEXT index on only name and deleted the ORDER BY statement, but it seems to make no difference. My indices are now:

Products(name) BTREE
Products(name,description) FULLTEXT
Products(name) FULLTEXT

EXPLAIN of the above query gives: (with indices) http://i.stack.imgur.com/8Fe8C.gif

Thanks in advance and sorry for my bad English.

Was it helpful?

Solution

read the following links about clustered primary keys:

http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html

http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/

MySQL and NoSQL: Help me to choose the right one

Any way to achieve fulltext-like search on InnoDB

How to avoid "Using temporary" in many-to-many queries?

60 million entries, select entries from a certain month. How to optimize database?

then redesign your product_stores table something along the lines of:

create table products_stores
(
store_id int unsigned not null,
product_id int unsigned not null,
...
primary key (store_id, product_id)
)
engine=innodb;

hope this helps :)

OTHER TIPS

Because you are looking for products from a specific store, I would have an index on the store ID AND the Name, then adjust the query to pre-qualify the products FROM the given store instead of looking at all products first.

SELECT STRAIGHT_JOIN
      P.id, 
      P.name, 
      P.drager, 
      P.import, 
      P.price, 
      P.description, 
      P.units 
   FROM 
      Product_Stores PS
         JOIN Products P
            on PS.Product_ID = P.ID
           AND P.Name like 'back%'
   WHERE
      PS.Store_ID = 1
   order by
      P.Description
   limit
      500
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top