leisure

JAVA - exceed,helloworld
随笔 - 50, 文章 - 0, 评论 - 11, 引用 - 0
数据加载中……

记一段mysql优化体验

今天优化了一个查询语句,觉得蛮可以的,拿出来跟大家分享一下,为方便起见,用了三个表作为示例说明。分别有:
tbl_commpany主要是记录厂商的信息,包括该厂商的状态。
tbl_product主要是记录产品的信息,包括产品的状态,与厂商信息表关联。
tbl_company_top主要记录厂商浏览访问的排行榜信息(按年)。
tbl_company(name, status)
tbl_product(name, company_id,status)
tbl_company_top(company_id,rank,count,year)
现在要查询显示:
查询按排行榜排序的前100个厂商列表,显示厂商名以及厂商下有多少产品数。
三星(1560)  HTC(581)  ……

思路是用 tbl_company_top(厂商排名表)与 b临时表(每个厂商对应的产品数表) 与 tbl_company表(需要根据厂商的状态进行过滤)三表关联:
SELECT 
  c.name, b.product_count
FROM 
  (SELECT * FROM tbl_company_top WHERE year = 2011) a,
  (SELECT company_id, COUNT(*) AS product_count FROM tbl_product WHERE status = 1 GROUP BY company_id) b,
  tbl_company c
WHERE 
  a.company_id = c.id
  AND b.company_id = c.id
  AND c.status = 1
ORDER BY a.rank,a.count DESC LIMIT 50;
查询了一下。速度非常慢。
以下是EXPLAIN的信息:


按照少关联,多筛选,尽可能减少最大条数再进行关联的原则。
原本打算在子查询中直接LIMIT掉50条数据。不幸的是:This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery

SELECT 
  b.copmany_id, COUNT(b.id), a.cnt
FROM
  (SELECT copmany_id, MAX(COUNT) AS cnt FROM tbl_company_top a WHERE year = 2011 GROUP BY copmany_id) a,
  tbl_product b,
  tbl_copmany c
WHERE
  b.company_id = a.company_id
  AND c.id = a.company_id
  AND b.status = 1
  AND c.status = 9
  GROUP BY b.company_id, a.cnt
  ORDER BY a.cnt DESC LIMIT 50;

EXPLAIN的信息如下:
此时,查询语句可以达到接受级别(当然视乎数据的级别)


另外,给必要的查询字段加上索引,也有不错的效果。

posted on 2011-10-09 12:20 leisure 阅读(278) 评论(0)  编辑  收藏 所属分类: database


只有注册用户登录后才能发表评论。


网站导航: