如何针对MyISAM表加速这个巨大的查询?

时间:2011-06-14 18:04:37

标签: mysql database-design

此查询针对单个表。该表有60个属性称为“attribute1”到“attribute60”,它们都是类型:

varchar(255)

还有一个名为“brand_id”的专栏:

int(11)

表中存在以下密钥:

brand_id, attribute1, attribute2, attribute3

查询如下:

SELECT distinct attribute1
from brands b inner join product_applications pa on pa.brand_id = b.id
where b.id in (1,372,373,374,375,376,378,381,452,
               453,454,455,456,457,458,461,474,476,
               544,480,563,508,512,513,516,517,519,520,521,
               522,524,525,527,528,529,533,538,539,540,542,
               546,547,548,555,556,557,642,643,644,645,646,
               647,648,649,650,651,652,653,654,655)

需要10秒钟。该表有5,735,673行。

此查询需要不超过2秒。我无法弄清楚如何编写它,或者我是否需要某种替代表结构来执行此操作。有人可以提供推荐吗?

我曾经在WHERE子句中使用IN,但是在另一个论坛中建议这种丑陋的方式因为连接而更快。我真的不知道这意味着什么,但它更快,但仍然非常慢。

+----+-------------+-------+-------+----------------------------------------+--------------------+---------+-----------+-------+-------------------------------------------+
| id | select_type | table | type  | possible_keys                          | key                | key_len | ref       | rows  | Extra                                     |
+----+-------------+-------+-------+----------------------------------------+--------------------+---------+-----------+-------+-------------------------------------------+
|  1 | SIMPLE      | b     | range | PRIMARY                                | PRIMARY            | 4       | NULL      |    60 | Using where; Using index; Using temporary | 
|  1 | SIMPLE      | pa    | ref   | brand_search_index,parttype_search_idx | brand_search_index | 5       | mcp5.b.id | 57356 | Using where; Using index                  | 
+----+-------------+-------+-------+----------------------------------------+--------------------+---------+-----------+-------+-------------------------------------------+
2 rows in set (0.04 sec)

2 个答案:

答案 0 :(得分:1)

这看起来像是一个奇怪的查询,所以我可能会遗漏一些东西,但我认为你可以用IN子句做到这一点:

SELECT distinct attribute1
from product_applications pa WHERE brand_id IN (1, 372, ..., 655)

我认为这更快 - 它肯定更干净 - 但如果不是,你可能需要添加一些关于索引的细节,可能是一个EXPLAIN QUERY等。

答案 1 :(得分:1)

你的桌子是这样的:

        brand...attr1......attr2..........attr3
        BRAND...CATEGORY...PRODTYPE....PRODUCT

e.g。

        DOVE....HOME.......SOAP.......dish washing liquid

您希望为指定的品牌列表获取一组独特的产品类别。但是你有超过500万种产品,因此单个表不能立即完成。通常处理此方法的方法是使用多个相关表:

       BRANDS(brandid, brandname)
       CATEGORIES (categoryid, categoryname)
       PRODTYPES (prodtypeid, prodtypename)
       BRANDCATEGORIES (brandid, categoryid) EDIT: put a unique constraint on (brandid, categoryid)
       PRODUCTS(brandid, categoryid, prodtypeid, productname)

然后,您的查询将是:

      select distinct categories.categoryid, categoryname
      from brands inner join categories
      on brand.brandid = brandcategories.brandid
      and categories.categoryid = brandcategories.categoryid
      where brands.brandid in ( .... )