【问题标题】:Speed up search query (large junction table)加快搜索查询(大型联结表)
【发布时间】:2011-12-14 11:54:34
【问题描述】:

我正在用 PHP/MYSQL 编写一个多商店网上商店应用程序。产品表有大约一百万条记录,目前我有 5 家商店,里面有所有产品,大约 3 家商店有一些产品。产品的价格有时因商店而异。因为应该可以为商店 2 添加或删除某些产品,所以我创建了一个联结表。我的表格如下所示:

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

搜索产品时,查询大约需要 20 秒。我向产品(名称,描述)+产品商店(产品ID,商店ID)添加了索引。有什么办法可以加快这个过程吗? products_stores 中的大多数记录都是相同的(store_id 除外),但我想保持灵活。

查询:

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

我只在 name 上添加了 FULLTEXT 索引并删除了 ORDER BY 语句,但似乎没有什么区别。我的索引现在是:

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

上述查询的解释给出:(带索引) http://i.stack.imgur.com/8Fe8C.gif

在此先感谢,并为我的英语不好感到抱歉。

【问题讨论】:

  • 你能告诉我们需要 20 秒的查询吗?
  • 当然,我添加了查询。
  • 您可以在查询中放置换行符。这样做可能会让您的生活更轻松。 :)
  • 有没有检查MySQL是否取索引(查询执行计划:dev.mysql.com/doc/refman/5.0/en/explain.html
  • 请发布创建表产品。仅查看数据类型。名称或描述是“文本”类型吗?那么你应该使用:dev.mysql.com/doc/refman/5.0/en/…

标签: php mysql performance junction


【解决方案1】:

阅读以下有关集群主键的链接:

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?

然后按照以下方式重新设计您的 product_stores 表:

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

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    因为您正在寻找来自特定商店的产品,所以我会在商店 ID 和名称上创建一个索引,然后调整查询以预先确定来自给定商店的产品,而不是先查看所有产品。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 2014-11-10
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 2012-05-01
      • 1970-01-01
      相关资源
      最近更新 更多